AnyCAD應用——修改指定點,線,面的座標實現物體移動

2023-07-01 15:00:57

課題需求: 三維模型位置隨實物位置改變而動態改變的功能,通過頂點位置座標的改變,修改模型在顯示中的位置。


功能驗證:目前,可通過選中頂點手動輸入座標的方式,模擬驗證此功能。


首先,點選「檔案」工具列,選擇匯入實體,匯入一個step檔案,這是一種常用的三維實體模型格式。

 

void OnOpenModel()
{
var dlg = new Microsoft.Win32.OpenFileDialog
{
DefaultExt = ".stp",
Filter = "Models (*.igs;*.iges;*.stp;*.step;*.brep;*.stl)|*.igs;*.iges;*.stp;*.step;*.brep;*.stl"
};
if (dlg.ShowDialog() != true)
return;

SceneNode? node = null;
ProgressView pv = new ProgressView(() =>
{
var shape = ShapeIO.Open(dlg.FileName);
if (shape == null)
return;
node = BrepSceneNode.Create(shape, null, null, 0, false);
});
pv.ShowDialog();

if (node == null)
return;

mRenderView.ShowSceneNode(node);
mRenderView.ZoomAll();
}


然後,在匯入的三維模型中選中某一點,即可在「操作物件」屬性欄中看到該點在世界座標系中的實際位置。

 

var item = itr.Current();
msg += $"\nNodeId: {item.GetNodeId()}";
msg += $"\nUserId: {item.GetUserId()}";
msg += $"\nShapeId: {item.GetShapeIndex()}";
msg += $"\nPrimitiveId: {item.GetPrimitiveIndex()}";
msg += $"\nType: {item.GetShapeType().ToString()}";
msg += $"\nTopoShapeId: {item.GetTopoShapeId().ToString()}";
var pt = item.GetPosition();
msg += $"\nPosition: {pt.x} {pt.y} {pt.z}";


如果需要修改該點的位置,可以點選「自定義位置調整」工具列,在「目標位置」屬性欄中輸入目標座標,或者使用滑鼠拖動該點,即可將目標頂點移動到所需位置。並且,您可通過點選軟體右上角位置方塊,觀察三維模型各個位置的動態變化。

 選擇頂點

 ViewStateGuard.SetPickFilter(EnumShapeFilter.VertexEdgeFace);

 對應的XAML程式碼

<Expander Header="操作物件" IsExpanded="True">
<StackPanel Margin="7,7,7,0" Orientation="Vertical">
<StackPanel Orientation="Horizontal" Margin="0,0,0,7">
<au:AuStepButton Content="選擇物件" Margin="0,0,7,0"
IsChecked ="{Binding SourceObjectChecked, Mode=OneWay}"
IsStateFocused="{Binding SourceObjectFocused, Mode=OneWay}"
StepName ="SourceObject"
Click="OnClickStep"/>
<au:AuImageButton Click="OnChoosePoint"
IsStateFocused="{Binding SourcePointFocused, Mode=OneWay}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,7">
<au:AuNumericBox Width="70" Value="{Binding SourcePointX}" Margin="0,0,7,0"/>
<au:AuNumericBox Width="70" Value="{Binding SourcePointY}" Margin="0,0,7,0"/>
<au:AuNumericBox Width="70" Value="{Binding SourcePointZ}" Margin="0,0,7,0"/>
</StackPanel>
</StackPanel>
</Expander>
<Expander Header="目標位置" IsExpanded="True">
<StackPanel Orientation="Horizontal" Margin="7,7,0,7">
<au:AuNumericBox Width="70" Value="{Binding TargetPointX}" Margin="0,0,7,0"/>
<au:AuNumericBox Width="70" Value="{Binding TargetPointY}" Margin="0,0,7,0"/>
<au:AuNumericBox Width="70" Value="{Binding TargetPointZ}" Margin="0,0,7,0"/>
</StackPanel>
</Expander>

對應的座標變數

GPnt _SourcePoint = new GPnt();
[ExpandXYZ]
public GPnt SourcePoint
{
get => _SourcePoint;
set
{
_SourcePoint.SetXYZ(value.XYZ());
OnPropertyChanged(nameof(SourcePoint));
OnPropertyChanged(nameof(SourcePointX));
OnPropertyChanged(nameof(SourcePointY));
OnPropertyChanged(nameof(SourcePointZ));
}
}

GPnt _TargetPoint = new GPnt();
[ExpandXYZ]
public GPnt TargetPoint
{
get => _TargetPoint;
set
{
_TargetPoint.SetXYZ(value.XYZ());
OnPropertyChanged(nameof(TargetPoint));
OnPropertyChanged(nameof(TargetPointX));
OnPropertyChanged(nameof(TargetPointY));
OnPropertyChanged(nameof(TargetPointZ));

UpdateObject();
}
}

應用變換

void UpdateObject()
{
if (_SourceObject == null)
{
return;
}

var vec = new GVec(_SourcePoint, _TargetPoint);
var trf = Matrix4.makeTranslation(Vector3.From(vec));

_SourceObject.SetTransform(trf);
_SourceObject.RequestUpdate();

ViewContext.RequestUpdate(EnumUpdateFlags.Scene);
}


此功能僅改變三維模型的三維座標,不改變模型本身的形狀。