Issue
I have a drawing which has two blocks, both of which refer to one block definition “aa”. In “aa”, there is one line and one circle. The tree of model is:
Root
0 (layer)
Insert1
Block Definition (aa)
Line
Circle
Insert2
Block Definition (aa)
Line
Circle
I wrote a code to generate the geometry of the selected node e.g. if you select the line: code returns two fragments. This means the API will return the fragments of all instances which refers to the same geometry in the block definition. So we have difficulty to know which geometry (GenerateSimplePrimitives ) returned from the fragment is the instance we are interested in.
Solution
You have a file that has a multiply-instanced node. This node has 1 fragment. If you select one instance of the node (i.e. you have a single path), then call Fragments() on the path, you will get two fragments.This is because the Fragments() function is getting hold of the node at the tail of the path, and then asking for the fragments for the node. This actually returns all the fragments for all instances of that node, so you get two fragments, not one. We have has a wish to return the geometry of the node that is selected.
About workaround: Fragment.Path tell which path it represents. Thus we could know which path is being checked and the which generated primitives represents this path. However Fragment.Path is a copy of the original path. So their nwID (or X64PtrVar) are different.
Fortunately, Path.ArrayData returns an array of indexes representing this path. e.g. assume the model tree is:
Root
Instance 1
Geometries >> (path1)
Instance 2
Geometries >> (path2)
If the current selection is the geometry under instance1, the Path.ArrayData is
1
1
1
While for the path2, Path.ArrayData is
1
2
1
So, with this, we could judge which path is being checked and filter the other irrelevant fragments. The feasible code could be:
// callback class to dump primitive
class CallbackGeomClass : InwSimplePrimitivesCB
{
#region InwSimplePrimitivesCB Members
public void Line(InwSimpleVertex v1, InwSimpleVertex v2)
{
// do nothing
}
public void Point(InwSimpleVertex v1)
{
// do nothing
}
public void SnapPoint(InwSimpleVertex v1)
{
// do nothing
}
public void Triangle(InwSimpleVertex v1, InwSimpleVertex v2, InwSimpleVertex v3)
{
// do nothing
}
#endregion
}
private void GenerateGeometry()
{
// define the callback class
CallbackGeomClass cbObj = new CallbackGeomClass();
// assume some nodes are selected
//check each path
foreach (InwOaPath oPath in
m_state.CurrentSelection.Paths())
{
//check each fragment of the path
foreach (InwOaFragment3 oFrag in oPath.Fragments())
{
// check if this fragment belongs to the current path
Array a1 = (Array)(object)oFrag.path.ArrayData;
Array a2 = (Array)(object)oPath.ArrayData;
bool isSame = true;
// this is a 1-dimension array
if (a1.GetLength(0) == a2.GetLength(0) &&
a1.GetLowerBound(0) == a2.GetLowerBound(0) &&
a1.GetUpperBound(0) == a2.GetUpperBound(0))
{
int i = a1.GetLowerBound(0);
for (; i <= a1.GetLength(0); i++)
{
int a1_value = (int)a1.GetValue(i);
int a2_value = (int)a2.GetValue(i);
if (a1_value != a2_value)
{
isSame = false;
break;
}
}
}
else
{
isSame = false;
}
// this is the path (instance) we need to check!
if (isSame)
// dump the geometry infomation
oFrag.GenerateSimplePrimitives(nwEVertexProperty.eNONE, cbObj);
}
}
}