Visualization after reshaping

Hi everybody,

I looked at the recent posts and decided to try reshaping myself. The first objective was to update a vertex of a shape I use the following code (I hope the formatting is right):

TopoDS_Shape shape ... //the shape to update
TopoDS_Vertex vertex ...//the vertex to update

gp_Pnt point = BRep_Tool::Pnt(vertex); array ^coordinates = gcnew array(3);

coordinates[0] = point.X();
coordinates[1] = point.Y();
coordinates[2] = point.Z();
BRep_Builder builder;
TopoDS_Vertex first, last, aVertex;
TopTools_IndexedMapOfShape edgesMap, verticesMap;
TopExp::MapShapes(shape, TopAbs_VERTEX, verticesMap);
TopExp::MapShapes(shape, TopAbs_EDGE, edgesMap);
Handle(ShapeBuild_ReShape) reshaper = new ShapeBuild_ReShape;
int vertexUpdates = 0;
for(int j=1; j { TopExp::Vertices( TopoDS::Edge(edgesMap(j)), first, last); if(first.IsEqual(vertex) || last.IsEqual(vertex))
{ if(first.IsEqual(vertex)) aVertex = first; else aVertex = last;

//value contains the changed coordinates of the vertex if( (value[0] != coordinates[0]) || (value[1] != coordinates[1]) || (value[2] != coordinates[2]))
{
builder.UpdateVertex(aVertex, gp_Pnt(value[0], value[1], value[2]), Precision::Confusion());
int key = verticesMap.FindIndex(aVertex); reshaper->Replace(verticesMap(key), aVertex); //reshaper->Replace(edgesMap(j), edgesMap(j)); vertexUpdates++; break;
}
}
}
if(vertexUpdates > 0)
{
shape = reshaper->Apply(shape);

ShapeFix_Shape fixer(shape); fixer.Perform(); shape = fixer.Shape();

aisShape = new AIS_Shape(shape);
... //Displaying
}

The are some problems with this code:
- the shape visualized in wireframe mode is the one before reshaping although the shaded mode displays the altered one correctly. This problem doesn't occur if I update (replace) the corresponding edges of the shape instead of vertices. However, in that case I have to create new TopoDS_Edge(s), which I would like to avoid.

- is this possible to make an automatic update of an AIS_Shape as soon as the underlying TopoDS_Shape changes?

- can reshaping be used to implement redo/undo functionalities (if I didn't want to use OCAF)?

Best regards
Pawel

Pawel's picture

hope it looks better this time...

gp_Pnt point = BRep_Tool::Pnt(vertex);
array ^coordinates = gcnew array(3);

coordinates[0] = point.X();
coordinates[1] = point.Y();
coordinates[2] = point.Z();

BRep_Builder builder;

TopoDS_Vertex first, last, aVertex;
TopTools_IndexedMapOfShape edgesMap, verticesMap;
TopExp::MapShapes(shape, TopAbs_VERTEX, verticesMap);
TopExp::MapShapes(shape, TopAbs_EDGE, edgesMap);
Handle(ShapeBuild_ReShape) reshaper = new ShapeBuild_ReShape;
int vertexUpdates = 0;

for(int j=1; j <= edgesMap.Extent(); j++)
{
TopExp::Vertices( TopoDS::Edge(edgesMap(j)), first, last);

if(first.IsEqual(vertex) || last.IsEqual(vertex))
{
if(first.IsEqual(vertex))
aVertex = first;
else
aVertex = last;

if( (value[0] != coordinates[0]) || (value[1] != coordinates[1]) || (value[2] != coordinates[2]))
{
builder.UpdateVertex(aVertex, gp_Pnt(value[0], value[1], value[2]), Precision::Confusion());

int key = verticesMap.FindIndex(aVertex);
reshaper->Replace(verticesMap(key), aVertex);
vertexUpdates++;
break;
}
}
}

TraceDebugFormattedStr(" VertexProperty Error. Updated vertices: ","%i",".",vertexUpdates);
if(vertexUpdates > 0)
{
shape = reshaper->Apply(shape);

ShapeFix_Shape fixer(shape);
fixer.Perform();
shape = fixer.Shape();

aisShape = new AIS_Shape(shape);
... //Displaying
}

Svetlozar Kostadinov's picture

There's no way to update the AIS presentation on shape-change automatically, because the presentation is computed one time from the TopoDS_Shape in the virtual method AIS_InteractiveObject::Compute(...). This method is called when you call aisShape->Display() or Redisplay().

Paul Jimenez's picture

Your code tries to achieve something I already got working... if I do really understand what you're trying to do. You're calling UpdateVertex, that's fine, but you're forgetting to call other important methods "upstream": UpdateEdge and UpdateFace. Furthermore, those two methods you're not calling are way more important than UpdateVertex. Check the source of BRepLib_MakeFace and BRepLib_MakeEdge to know what you have to create in order to update (actually, how to re-create surfaces and curves).

Getting the AIS_Shape to update itself when the inner TopoDS_Shape changes... that'd be great, but I didn't find a way to do that. Instead, I have to manually call the Set method of AIS_Shape to set the shape, again, followed by a call to Redisplay in AIS_InteractiveContext with that AIS_Shape to re-calculate the presentation and selection.

I do really wish I could share the code that does that, but it's part of the work I've done for the company. Giving you hints doesn't harm, though.

My experience is discussed here: http://www.opencascade.org/org/forum/thread_14745/

I hope you get it working now that you know where to look for.

Pawel's picture

Thank you for the comments guys!

Paul, I was actually a bit "inspired" by your earlier posts on this topic and so decided to try reshaping myself.

Originally I made some tests with updating edges (with better results than with the code above - at least at first glance) but then I thought: updating the underlying vertex should do the job cause is means updating the base shape.

Well, I'll keep on testing and let you know.

Regards
Pawel