1 // File: BRepTools_Modifier_21423.cxx
2 // Created: Thu Aug 25 10:48:00 1994
3 // Author: Jacques GOUSSARD
6 // IFV 04.06.99 - PRO18974 - processing of INTERNAL shapes.
8 #include <BRepTools_Modifier_21423.hxx>
10 //#include <Standard_NoSuchObject.hxx>
11 #include <BRepTools_Modification.hxx>
13 #include <TopoDS_Iterator.hxx>
14 #include <TopoDS_Vertex.hxx>
15 #include <TopoDS_Edge.hxx>
16 #include <TopoDS_Face.hxx>
17 #include <TopoDS_Shape.hxx>
18 #include <TopExp_Explorer.hxx>
19 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
20 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
21 #include <TopTools_ListOfShape.hxx>
22 #include <TopTools_ListIteratorOfListOfShape.hxx>
23 #include <TColStd_ListOfTransient.hxx>
24 #include <TColStd_ListIteratorOfListOfTransient.hxx>
27 #include <Poly_Triangulation.hxx>
28 #include <Poly_Polygon3D.hxx>
29 #include <BRepMesh_IncrementalMesh.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRep_Tool.hxx>
36 #include <BRepTools.hxx>
43 #include <Standard_NullObject.hxx>
44 #include <gp_Trsf.hxx>
45 #include <BRepTools_TrsfModification.hxx>
49 //=======================================================================
50 //function : BRepTools_Modifier_21423
52 //=======================================================================
54 BRepTools_Modifier_21423::BRepTools_Modifier_21423 ():myDone(Standard_False)
57 //=======================================================================
58 //function : BRepTools_Modifier_21423
60 //=======================================================================
62 BRepTools_Modifier_21423::BRepTools_Modifier_21423 (const TopoDS_Shape& S) :
63 myShape(S),myDone(Standard_False)
69 //=======================================================================
70 //function : BRepTools_Modifier_21423
72 //=======================================================================
74 BRepTools_Modifier_21423::BRepTools_Modifier_21423
75 (const TopoDS_Shape& S,
76 const Handle(BRepTools_Modification)& M) : myShape(S),myDone(Standard_False)
84 //=======================================================================
87 //=======================================================================
89 void BRepTools_Modifier_21423::Init(const TopoDS_Shape& S)
92 myDone = Standard_False;
98 //=======================================================================
101 //=======================================================================
103 void BRepTools_Modifier_21423::Perform(const Handle(BRepTools_Modification)& M)
105 if (myShape.IsNull()) {
106 Standard_NullObject::Raise();
108 TopTools_DataMapIteratorOfDataMapOfShapeShape theIter(myMap);
110 // Set to Null the value of shapes, in case when another modification is applied to the start shape.
112 if (!theIter.Value().IsNull()) {
113 while (theIter.More()) {
114 myMap(theIter.Value()).Nullify();
121 while (theIter.More()) {
122 Rebuild(theIter.Key(),M);
127 Rebuild(myShape, M, 0.);
129 if (myShape.ShapeType() == TopAbs_FACE) {
130 if (myShape.Orientation() == TopAbs_REVERSED) {
131 myMap(myShape).Reverse();
134 myMap(myShape).Orientation(myShape.Orientation());
138 myMap(myShape).Orientation(myShape.Orientation());
141 // Update the continuities
143 TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
144 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,theEFMap);
148 Standard_Boolean RecomputeTriangles = Standard_False;
149 Standard_Real MaxDeflection = RealFirst();
150 Handle(Poly_Triangulation) Tr;
151 Handle(Poly_Polygon3D) Po;
155 while (theIter.More()) {
156 const TopoDS_Shape& S = theIter.Key();
158 if (S.ShapeType() == TopAbs_FACE && !S.IsSame(theIter.Value())) {
159 Tr = BRep_Tool::Triangulation(TopoDS::Face(S),Loc);
161 RecomputeTriangles = Standard_True;
162 MaxDeflection = Max(MaxDeflection,Tr->Deflection());
165 else */ if (S.ShapeType() == TopAbs_EDGE && !S.IsSame(theIter.Value())) {
166 const TopoDS_Edge& edg = TopoDS::Edge(S);
168 Po = BRep_Tool::Polygon3D(edg,Loc);
170 RecomputeTriangles = Standard_True;
171 MaxDeflection = Max(MaxDeflection,Po->Deflection());
174 TopTools_ListIteratorOfListOfShape it;
175 it.Initialize(theEFMap.FindFromKey(edg));
177 while (it.More() && F2.IsNull()) {
179 F1 = TopoDS::Face(it.Value());
182 F2 = TopoDS::Face(it.Value());
187 const TopoDS_Edge& newedg = TopoDS::Edge(myMap(edg));
188 const TopoDS_Face& newf1 = TopoDS::Face(myMap(F1));
189 const TopoDS_Face& newf2 = TopoDS::Face(myMap(F2));
190 GeomAbs_Shape Newcont = M->Continuity(edg,F1,F2,newedg,newf1,newf2);
191 if (Newcont > GeomAbs_C0) {
192 B.Continuity(newedg,newf1,newf2,Newcont);
199 if (RecomputeTriangles) {
200 BRepMesh_IncrementalMesh(myMap(myShape),MaxDeflection);
204 myDone = Standard_True;
208 //=======================================================================
211 //=======================================================================
213 void BRepTools_Modifier_21423::Put(const TopoDS_Shape& S)
215 if (!myMap.IsBound(S)) {
216 myMap.Bind(S,TopoDS_Shape());
217 for(TopoDS_Iterator theIterator(S,Standard_False);theIterator.More();theIterator.Next()) {
219 Put(theIterator.Value());
224 //=======================================================================
227 //=======================================================================
229 Standard_Boolean BRepTools_Modifier_21423::Rebuild
230 (const TopoDS_Shape& S,
231 const Handle(BRepTools_Modification)& M,
232 const Standard_Real Tol)
234 TopoDS_Shape& result = myMap(S);
235 // if (!result.IsNull()) return ! S.IsEqual(result);
236 if (!result.IsNull()) return ! S.IsSame(result);
237 Standard_Boolean rebuild = Standard_False, RevWires = Standard_False;
238 TopAbs_Orientation ResOr = TopAbs_FORWARD;
240 Standard_Real tol = Tol;
241 Standard_Boolean No3DCurve = Standard_False; // en fait, si on n`a pas de
242 //modif geometry 3d , it is necessary to test the existence of a curve 3d.
246 TopAbs_ShapeEnum ts = S.ShapeType();
250 Standard_Boolean RevFace;
251 Handle(Geom_Surface) surface;
252 TopLoc_Location location;
253 rebuild = M->NewSurface(TopoDS::Face(S),surface,location,tol,
255 tol = Max(Tol,tol); //OCC217
257 B.MakeFace(TopoDS::Face(result),surface,
258 location.Predivided(S.Location()),tol);
259 result.Location(S.Location());
260 // result.Orientation(S.Orientation());
262 ResOr = TopAbs_REVERSED;
264 // set specifics flags of a Face
265 B.NaturalRestriction(TopoDS::Face(result),
266 BRep_Tool::NaturalRestriction(TopoDS::Face(S)));
273 Handle(Geom_Curve) curve;
274 TopLoc_Location location;
275 rebuild = M->NewCurve(TopoDS::Edge(S),curve,location,tol);
276 tol = Max(Tol,tol); //OCC217
278 if (curve.IsNull()) {
279 B.MakeEdge(TopoDS::Edge(result));
280 B.Degenerated(TopoDS::Edge(result),
281 BRep_Tool::Degenerated(TopoDS::Edge(S)));
282 B.UpdateEdge(TopoDS::Edge(result),tol); //OCC217
283 No3DCurve = Standard_True;
286 B.MakeEdge(TopoDS::Edge(result),curve,
287 location.Predivided(S.Location()),tol);
288 No3DCurve = Standard_False;
290 result.Location(S.Location());
291 // result.Orientation(S.Orientation());
293 // set specifics flags of an Edge
294 B.SameParameter(TopoDS::Edge(result),
295 BRep_Tool::SameParameter(TopoDS::Edge(S)));
296 B.SameRange(TopoDS::Edge(result),
297 BRep_Tool::SameRange(TopoDS::Edge(S)));
305 rebuild = M->NewPoint(TopoDS::Vertex(S),vtx,tol);
306 tol = Max(Tol, tol); //OCC217
308 B.MakeVertex(TopoDS::Vertex(result),vtx,tol);
318 // rebuild sub-shapes and test new sub-shape ?
320 Standard_Boolean newgeom = rebuild;
324 for (it.Initialize(S, Standard_False); it.More(); it.Next()) {
325 // always call Rebuild
326 Standard_Boolean subrebuilt = Rebuild(it.Value(), M, tol);
327 rebuild = subrebuilt || rebuild ;
330 // make an empty copy
331 if (rebuild && !newgeom) {
332 result = S.EmptyCopied();
333 result.Orientation(TopAbs_FORWARD);
336 // copy the sub-elements
339 TopAbs_Orientation orient;
340 for (it.Initialize(S,Standard_False); it.More(); it.Next()) {
341 orient = it.Value().Orientation();
342 if (RevWires || myMap(it.Value()).Orientation() == TopAbs_REVERSED) {
343 orient = TopAbs::Reverse(orient);
345 B.Add(result,myMap(it.Value()).Oriented(orient));
349 if (ts == TopAbs_FACE) {
351 Handle(Geom2d_Curve) curve2d; //,curve2d1;
352 TopoDS_Face face = TopoDS::Face(S);
353 TopAbs_Orientation fcor = face.Orientation();
354 if(fcor != TopAbs_REVERSED) fcor = TopAbs_FORWARD;
356 TopExp_Explorer ex(face.Oriented(fcor),TopAbs_EDGE);
357 for (;ex.More(); ex.Next())
359 const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
361 if (M->NewCurve2d(edge, face,TopoDS::Edge(myMap(ex.Current())),
362 TopoDS::Face(result),curve2d, tol))
364 tol = Max(Tol,tol); //OCC217
365 // rem dub 16/09/97 : Make constant topology or not make at all.
366 // Do not make if CopySurface = 1
367 // Atention, TRUE sewing edges (RealyClosed)
368 // stay even if CopySurface is true.
370 // check that edge contains two pcurves on this surface:
371 // either it is true seam on the current face, or belongs to two faces
372 // built on that same surface (see OCC21772)
373 // Note: this check could be made separate method in BRepTools
374 Standard_Boolean isClosed = Standard_False;
375 if(BRep_Tool::IsClosed(edge,face))
377 isClosed = ( ! newgeom || BRepTools::IsReallyClosed(edge,face) );
380 TopLoc_Location aLoc;
381 TopoDS_Shape resface = (myMap.IsBound(face) ? myMap(face) : face);
384 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(resface), aLoc);
385 // check other faces sharing the same surface
386 TopExp_Explorer aExpF(myShape,TopAbs_FACE);
387 for( ; aExpF.More() && !isClosed; aExpF.Next())
389 TopoDS_Face anOther = TopoDS::Face(aExpF.Current());
390 if(anOther.IsSame(face))
392 TopoDS_Shape resface2 = (myMap.IsBound(anOther) ? myMap(anOther) : anOther);
393 if(resface2.IsNull())
395 TopLoc_Location anOtherLoc;
396 Handle(Geom_Surface) anOtherSurf =
397 BRep_Tool::Surface(TopoDS::Face(resface2), anOtherLoc);
398 if ( aSurf == anOtherSurf && aLoc.IsEqual (anOtherLoc) )
400 TopExp_Explorer aExpE(anOther,TopAbs_EDGE);
401 for( ; aExpE.More() && !isClosed ; aExpE.Next())
402 isClosed = edge.IsSame(aExpE.Current());
409 TopoDS_Edge CurE = TopoDS::Edge(myMap(edge));
410 TopoDS_Shape aLocalResult = result;
411 aLocalResult.Orientation(TopAbs_FORWARD);
412 TopoDS_Face CurF = TopoDS::Face(aLocalResult);
413 Handle(Geom2d_Curve) curve2d1, currcurv;
415 if ((!RevWires && fcor != edge.Orientation()) ||
416 ( RevWires && fcor == edge.Orientation())) {
417 CurE.Orientation(TopAbs_FORWARD);
418 curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
419 if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
420 B.UpdateEdge (CurE, curve2d1, curve2d, CurF, tol);
423 CurE.Orientation(TopAbs_REVERSED);
424 curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
425 if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
426 B.UpdateEdge (CurE, curve2d, curve2d1, CurF, tol);
428 currcurv = BRep_Tool::CurveOnSurface(edge,face,f,l);
432 B.UpdateEdge(TopoDS::Edge(myMap(ex.Current())),
434 TopoDS::Face(result), tol);
437 TopLoc_Location theLoc;
438 Standard_Real theF,theL;
439 Handle(Geom_Curve) C3D =
440 BRep_Tool::Curve(TopoDS::Edge(myMap(ex.Current())),
442 if (C3D.IsNull()) { // Update vertices
444 TopExp_Explorer ex2(edge,TopAbs_VERTEX);
446 const TopoDS_Vertex& vertex = TopoDS::Vertex(ex2.Current());
447 if (!M->NewParameter(vertex, edge, param, tol)) {
448 //tol = BRep_Tool::Tolerance(vertex);
449 tol = Max(Tol, BRep_Tool::Tolerance(vertex)); //OCC217
450 param = BRep_Tool::Parameter(vertex,edge);
453 TopAbs_Orientation vtxrelat = vertex.Orientation();
454 if (edge.Orientation() == TopAbs_REVERSED) {
455 // Update considere l'edge FORWARD, et le vertex en relatif
456 vtxrelat= TopAbs::Reverse(vtxrelat);
458 // if (myMap(edge).Orientation() == TopAbs_REVERSED) {
459 // vtxrelat= TopAbs::Reverse(vtxrelat);
461 TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
462 aLocalVertex.Orientation(vtxrelat);
463 // B.UpdateVertex(TopoDS::Vertex
464 // (myMap(vertex).Oriented(vtxrelat)),
465 B.UpdateVertex(aLocalVertex,
467 TopoDS::Edge(myMap(edge)),
478 // else if (ts == TopAbs_EDGE) {
479 else if (ts == TopAbs_EDGE && !No3DCurve) {
482 const TopoDS_Edge& edge = TopoDS::Edge(S);
483 TopAbs_Orientation edor = edge.Orientation();
484 if(edor != TopAbs_REVERSED) edor = TopAbs_FORWARD;
485 TopExp_Explorer ex(edge.Oriented(edor), TopAbs_VERTEX);
487 const TopoDS_Vertex& vertex = TopoDS::Vertex(ex.Current());
489 if (!M->NewParameter(vertex, edge, param, tol)) {
490 //tol = BRep_Tool::Tolerance(vertex);
491 tol = Max(Tol, BRep_Tool::Tolerance(vertex)); //OCC217
492 param = BRep_Tool::Parameter(vertex,edge);
496 TopAbs_Orientation vtxrelat = vertex.Orientation();
497 if (edor == TopAbs_REVERSED) {
498 // Update considere l'edge FORWARD, et le vertex en relatif
499 vtxrelat= TopAbs::Reverse(vtxrelat);
501 // if (result.Orientation() == TopAbs_REVERSED) {
502 // vtxrelat= TopAbs::Reverse(vtxrelat);
504 TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
505 aLocalVertex.Orientation(vtxrelat);
506 // B.UpdateVertex(TopoDS::Vertex
507 // (myMap(vertex).Oriented(vtxrelat)),
508 B.UpdateVertex(aLocalVertex,
510 TopoDS::Edge(result),
520 result.Orientable(S.Orientable());
521 result.Closed(S.Closed());
522 result.Infinite(S.Infinite());
527 // Set flag of the shape.
528 result.Orientation(ResOr);
530 result.Free (S.Free());
531 result.Modified (S.Modified());
532 result.Checked (S.Checked());
533 result.Orientable(S.Orientable());
534 result.Closed (S.Closed());
535 result.Infinite (S.Infinite());
536 result.Convex (S.Convex());