0022312: Translation of french commentaries in OCCT files
[occt.git] / src / BRepTools / BRepTools_Modifier.cxx
CommitLineData
7fd59977 1// File: BRepTools_Modifier.cxx
2// Created: Thu Aug 25 10:48:00 1994
3// Author: Jacques GOUSSARD
4// <jag@ecolox>
5
0d969553 6// IFV 04.06.99 - PRO18974 - processing of INTERNAL shapes.
7fd59977 7
8#include <BRepTools_Modifier.ixx>
9
10#include <TopoDS_Iterator.hxx>
11#include <TopoDS_Vertex.hxx>
12#include <TopoDS_Edge.hxx>
13#include <TopoDS_Face.hxx>
14#include <TopoDS_Shape.hxx>
15#include <TopExp_Explorer.hxx>
16#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
17#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
18#include <TopTools_ListOfShape.hxx>
19#include <TopTools_ListIteratorOfListOfShape.hxx>
20#include <TColStd_ListOfTransient.hxx>
21#include <TColStd_ListIteratorOfListOfTransient.hxx>
22
23#if 0
24#include <Poly_Triangulation.hxx>
25#include <Poly_Polygon3D.hxx>
26#include <BRepMesh_IncrementalMesh.hxx>
27#endif
28
29#include <Geom2d_Line.hxx>
30#include <BRep_Builder.hxx>
31#include <BRep_Tool.hxx>
32#include <TopoDS.hxx>
33#include <BRepTools.hxx>
34#include <TopAbs.hxx>
35#include <TopExp.hxx>
36#include <gp_Pnt.hxx>
37
38#include <gp.hxx>
39
40#include <Standard_NullObject.hxx>
41#include <gp_Trsf.hxx>
42#include <BRepTools_TrsfModification.hxx>
43
44
45
46//=======================================================================
47//function : BRepTools_Modifier
48//purpose :
49//=======================================================================
50
51BRepTools_Modifier::BRepTools_Modifier ():myDone(Standard_False)
52{}
53
54//=======================================================================
55//function : BRepTools_Modifier
56//purpose :
57//=======================================================================
58
59BRepTools_Modifier::BRepTools_Modifier (const TopoDS_Shape& S) :
60 myShape(S),myDone(Standard_False)
61{
62 myMap.Clear();
63 Put(S);
64}
65
66//=======================================================================
67//function : BRepTools_Modifier
68//purpose :
69//=======================================================================
70
71BRepTools_Modifier::BRepTools_Modifier
72 (const TopoDS_Shape& S,
73 const Handle(BRepTools_Modification)& M) : myShape(S),myDone(Standard_False)
74{
75 myMap.Clear();
76 Put(S);
77 Perform(M);
78}
79
80
81//=======================================================================
82//function : Init
83//purpose :
84//=======================================================================
85
86void BRepTools_Modifier::Init(const TopoDS_Shape& S)
87{
88 myShape = S;
89 myDone = Standard_False;
90 myMap.Clear();
91 Put(S);
92}
93
94
95//=======================================================================
96//function : Perform
97//purpose :
98//=======================================================================
99
100void BRepTools_Modifier::Perform(const Handle(BRepTools_Modification)& M)
101{
102 if (myShape.IsNull()) {
103 Standard_NullObject::Raise();
104 }
105 TopTools_DataMapIteratorOfDataMapOfShapeShape theIter(myMap);
106
0d969553 107 // Set to Null the value of shapes, in case when another modification is applied to the start shape.
7fd59977 108
109 if (!theIter.Value().IsNull()) {
110 while (theIter.More()) {
111 myMap(theIter.Value()).Nullify();
112 theIter.Next();
113 }
114 theIter.Reset();
115 }
116
117 /*
118 while (theIter.More()) {
119 Rebuild(theIter.Key(),M);
120 theIter.Next();
121 }
122 */
123
124 Rebuild(myShape,M);
125
126 if (myShape.ShapeType() == TopAbs_FACE) {
127 if (myShape.Orientation() == TopAbs_REVERSED) {
128 myMap(myShape).Reverse();
129 }
130 else{
131 myMap(myShape).Orientation(myShape.Orientation());
132 }
133 }
134 else {
135 myMap(myShape).Orientation(myShape.Orientation());
136 }
137
0d969553 138 // Update the continuities
7fd59977 139
140 TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
141 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,theEFMap);
142 BRep_Builder B;
143
144/*
145 Standard_Boolean RecomputeTriangles = Standard_False;
146 Standard_Real MaxDeflection = RealFirst();
147 Handle(Poly_Triangulation) Tr;
148 Handle(Poly_Polygon3D) Po;
149 TopLoc_Location Loc;
150*/
151
152 while (theIter.More()) {
153 const TopoDS_Shape& S = theIter.Key();
154/*
155 if (S.ShapeType() == TopAbs_FACE && !S.IsSame(theIter.Value())) {
156 Tr = BRep_Tool::Triangulation(TopoDS::Face(S),Loc);
157 if (!Tr.IsNull()) {
158 RecomputeTriangles = Standard_True;
159 MaxDeflection = Max(MaxDeflection,Tr->Deflection());
160 }
161 }
162 else */ if (S.ShapeType() == TopAbs_EDGE && !S.IsSame(theIter.Value())) {
163 const TopoDS_Edge& edg = TopoDS::Edge(S);
164/*
165 Po = BRep_Tool::Polygon3D(edg,Loc);
166 if (!Po.IsNull()) {
167 RecomputeTriangles = Standard_True;
168 MaxDeflection = Max(MaxDeflection,Po->Deflection());
169 }
170*/
171 TopTools_ListIteratorOfListOfShape it;
172 it.Initialize(theEFMap.FindFromKey(edg));
173 TopoDS_Face F1,F2;
174 while (it.More() && F2.IsNull()) {
175 if (F1.IsNull()) {
176 F1 = TopoDS::Face(it.Value());
177 }
178 else {
179 F2 = TopoDS::Face(it.Value());
180 }
181 it.Next();
182 }
183 if (!F2.IsNull()) {
184 const TopoDS_Edge& newedg = TopoDS::Edge(myMap(edg));
185 const TopoDS_Face& newf1 = TopoDS::Face(myMap(F1));
186 const TopoDS_Face& newf2 = TopoDS::Face(myMap(F2));
187 GeomAbs_Shape Newcont = M->Continuity(edg,F1,F2,newedg,newf1,newf2);
188 if (Newcont > GeomAbs_C0) {
189 B.Continuity(newedg,newf1,newf2,Newcont);
190 }
191 }
192 }
193 theIter.Next();
194 }
195/*
196 if (RecomputeTriangles) {
197 BRepMesh_IncrementalMesh(myMap(myShape),MaxDeflection);
198 }
199*/
200
201 myDone = Standard_True;
202
203}
204
205//=======================================================================
206//function : Put
207//purpose :
208//=======================================================================
209
210void BRepTools_Modifier::Put(const TopoDS_Shape& S)
211{
212 if (!myMap.IsBound(S)) {
213 myMap.Bind(S,TopoDS_Shape());
214 for(TopoDS_Iterator theIterator(S,Standard_False);theIterator.More();theIterator.Next()) {
215
216 Put(theIterator.Value());
217 }
218 }
219}
220
221//=======================================================================
222//function : Rebuild
223//purpose :
224//=======================================================================
225
226Standard_Boolean BRepTools_Modifier::Rebuild
227 (const TopoDS_Shape& S,
228 const Handle(BRepTools_Modification)& M)
229{
230 TopoDS_Shape& result = myMap(S);
231// if (!result.IsNull()) return ! S.IsEqual(result);
232 if (!result.IsNull()) return ! S.IsSame(result);
233 Standard_Boolean rebuild = Standard_False, RevWires = Standard_False;
234 TopAbs_Orientation ResOr = TopAbs_FORWARD;
235 BRep_Builder B;
236 Standard_Real tol;
237 Standard_Boolean No3DCurve = Standard_False; // en fait, si on n`a pas de
0d969553 238 //modif geometry 3d , it is necessary to test the existence of a curve 3d.
7fd59977 239
240 // new geometry ?
241
242 TopAbs_ShapeEnum ts = S.ShapeType();
243 switch (ts) {
244 case TopAbs_FACE:
245 {
246 Standard_Boolean RevFace;
247 Handle(Geom_Surface) surface;
248 TopLoc_Location location;
249 rebuild = M->NewSurface(TopoDS::Face(S),surface,location,tol,
250 RevWires,RevFace);
251 if (rebuild) {
252 B.MakeFace(TopoDS::Face(result),surface,
253 location.Predivided(S.Location()),tol);
254 result.Location(S.Location());
255// result.Orientation(S.Orientation());
256 if (RevFace) {
257 ResOr = TopAbs_REVERSED;
258 }
259 // set specifics flags of a Face
260 B.NaturalRestriction(TopoDS::Face(result),
261 BRep_Tool::NaturalRestriction(TopoDS::Face(S)));
262 }
263 }
264 break;
265
266 case TopAbs_EDGE:
267 {
268 Handle(Geom_Curve) curve;
269 TopLoc_Location location;
270 rebuild = M->NewCurve(TopoDS::Edge(S),curve,location,tol);
271 if (rebuild) {
272 if (curve.IsNull()) {
273 B.MakeEdge(TopoDS::Edge(result));
274 B.Degenerated(TopoDS::Edge(result),
275 BRep_Tool::Degenerated(TopoDS::Edge(S)));
276 B.UpdateEdge(TopoDS::Edge(result),tol); //OCC217
277 No3DCurve = Standard_True;
278 }
279 else {
280 B.MakeEdge(TopoDS::Edge(result),curve,
281 location.Predivided(S.Location()),tol);
282 No3DCurve = Standard_False;
283 }
284 result.Location(S.Location());
285// result.Orientation(S.Orientation());
286
287 // set specifics flags of an Edge
288 B.SameParameter(TopoDS::Edge(result),
289 BRep_Tool::SameParameter(TopoDS::Edge(S)));
290 B.SameRange(TopoDS::Edge(result),
291 BRep_Tool::SameRange(TopoDS::Edge(S)));
292 }
293 }
294 break;
295
296 case TopAbs_VERTEX:
297 {
298 gp_Pnt vtx;
299 rebuild = M->NewPoint(TopoDS::Vertex(S),vtx,tol);
300 if (rebuild) {
301 B.MakeVertex(TopoDS::Vertex(result),vtx,tol);
302 }
303 }
304 break;
305
306 default:
307 {
308 }
309 }
310
311 // rebuild sub-shapes and test new sub-shape ?
312
313 Standard_Boolean newgeom = rebuild;
314
315 TopoDS_Iterator it;
316
317 for (it.Initialize(S, Standard_False); it.More(); it.Next()) {
318 // always call Rebuild
319 Standard_Boolean subrebuilt = Rebuild(it.Value(),M);
320 rebuild = subrebuilt || rebuild ;
321 }
322
323 // make an empty copy
324 if (rebuild && !newgeom) {
325 result = S.EmptyCopied();
326 result.Orientation(TopAbs_FORWARD);
327 }
328
329 // copy the sub-elements
330
331 if (rebuild) {
332 TopAbs_Orientation orient;
333 for (it.Initialize(S,Standard_False); it.More(); it.Next()) {
334 orient = it.Value().Orientation();
335 if (RevWires || myMap(it.Value()).Orientation() == TopAbs_REVERSED) {
336 orient = TopAbs::Reverse(orient);
337 }
338 B.Add(result,myMap(it.Value()).Oriented(orient));
339 }
340
341
342 if (ts == TopAbs_FACE) {
343 // pcurves
344 Handle(Geom2d_Curve) curve2d; //,curve2d1;
345 TopoDS_Face face = TopoDS::Face(S);
346 TopAbs_Orientation fcor = face.Orientation();
347 if(fcor != TopAbs_REVERSED) fcor = TopAbs_FORWARD;
348
349 TopExp_Explorer ex(face.Oriented(fcor),TopAbs_EDGE);
350 for (;ex.More(); ex.Next())
351 {
352 const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
353
354 if (M->NewCurve2d(edge, face,TopoDS::Edge(myMap(ex.Current())),
355 TopoDS::Face(result),curve2d, tol))
356 {
0d969553
Y
357 // rem dub 16/09/97 : Make constant topology or not make at all.
358 // Do not make if CopySurface = 1
359 // Atention, TRUE sewing edges (RealyClosed)
360 // stay even if CopySurface is true.
7fd59977 361
362 // check that edge contains two pcurves on this surface:
363 // either it is true seam on the current face, or belongs to two faces
364 // built on that same surface (see OCC21772)
365 // Note: this check could be made separate method in BRepTools
366 Standard_Boolean isClosed = Standard_False;
367 if(BRep_Tool::IsClosed(edge,face))
368 {
369 isClosed = ( ! newgeom || BRepTools::IsReallyClosed(edge,face) );
370 if ( ! isClosed )
371 {
372 TopLoc_Location aLoc;
373 TopoDS_Shape resface = (myMap.IsBound(face) ? myMap(face) : face);
374 if(resface.IsNull())
375 resface = face;
376 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(resface), aLoc);
377 // check other faces sharing the same surface
378 TopExp_Explorer aExpF(myShape,TopAbs_FACE);
379 for( ; aExpF.More() && !isClosed; aExpF.Next())
380 {
381 TopoDS_Face anOther = TopoDS::Face(aExpF.Current());
382 if(anOther.IsSame(face))
383 continue;
384 TopoDS_Shape resface2 = (myMap.IsBound(anOther) ? myMap(anOther) : anOther);
385 if(resface2.IsNull())
386 resface2 = anOther;
387 TopLoc_Location anOtherLoc;
388 Handle(Geom_Surface) anOtherSurf =
389 BRep_Tool::Surface(TopoDS::Face(resface2), anOtherLoc);
390 if ( aSurf == anOtherSurf && aLoc.IsEqual (anOtherLoc) )
391 {
392 TopExp_Explorer aExpE(anOther,TopAbs_EDGE);
393 for( ; aExpE.More() && !isClosed ; aExpE.Next())
394 isClosed = edge.IsSame(aExpE.Current());
395 }
396 }
397 }
398 }
399 if (isClosed)
400 {
401 TopoDS_Edge CurE = TopoDS::Edge(myMap(edge));
402 TopoDS_Shape aLocalResult = result;
403 aLocalResult.Orientation(TopAbs_FORWARD);
404 TopoDS_Face CurF = TopoDS::Face(aLocalResult);
405 Handle(Geom2d_Curve) curve2d1, currcurv;
406 Standard_Real f,l;
407 if ((!RevWires && fcor != edge.Orientation()) ||
408 ( RevWires && fcor == edge.Orientation())) {
409 CurE.Orientation(TopAbs_FORWARD);
410 curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
411 if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
412 B.UpdateEdge (CurE, curve2d1, curve2d, CurF, 0.);
413 }
414 else {
415 CurE.Orientation(TopAbs_REVERSED);
416 curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
417 if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
418 B.UpdateEdge (CurE, curve2d, curve2d1, CurF, 0.);
419 }
420 currcurv = BRep_Tool::CurveOnSurface(edge,face,f,l);
421 B.Range(edge,f,l);
422 }
423 else {
424 B.UpdateEdge(TopoDS::Edge(myMap(ex.Current())),
425 curve2d,
426 TopoDS::Face(result), 0.);
427 }
428
429 TopLoc_Location theLoc;
430 Standard_Real theF,theL;
431 Handle(Geom_Curve) C3D =
432 BRep_Tool::Curve(TopoDS::Edge(myMap(ex.Current())),
433 theLoc,theF,theL);
434 if (C3D.IsNull()) { // Update vertices
435 Standard_Real param;
436 TopExp_Explorer ex2(edge,TopAbs_VERTEX);
437 while (ex2.More()) {
438 const TopoDS_Vertex& vertex = TopoDS::Vertex(ex2.Current());
439 if (!M->NewParameter(vertex, edge, param, tol)) {
440 tol = BRep_Tool::Tolerance(vertex);
441 param = BRep_Tool::Parameter(vertex,edge);
442 }
443
444 TopAbs_Orientation vtxrelat = vertex.Orientation();
445 if (edge.Orientation() == TopAbs_REVERSED) {
446 // Update considere l'edge FORWARD, et le vertex en relatif
447 vtxrelat= TopAbs::Reverse(vtxrelat);
448 }
449// if (myMap(edge).Orientation() == TopAbs_REVERSED) {
450// vtxrelat= TopAbs::Reverse(vtxrelat);
451// }
452 TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
453 aLocalVertex.Orientation(vtxrelat);
454// B.UpdateVertex(TopoDS::Vertex
455// (myMap(vertex).Oriented(vtxrelat)),
456 B.UpdateVertex(aLocalVertex,
457 param,
458 TopoDS::Edge(myMap(edge)),
459 tol);
460 ex2.Next();
461 }
462 }
463
464 }
465 }
466
467 }
468
469// else if (ts == TopAbs_EDGE) {
470 else if (ts == TopAbs_EDGE && !No3DCurve) {
471 // Vertices
472 Standard_Real param;
473 const TopoDS_Edge& edge = TopoDS::Edge(S);
474 TopAbs_Orientation edor = edge.Orientation();
475 if(edor != TopAbs_REVERSED) edor = TopAbs_FORWARD;
476 TopExp_Explorer ex(edge.Oriented(edor), TopAbs_VERTEX);
477 while (ex.More()) {
478 const TopoDS_Vertex& vertex = TopoDS::Vertex(ex.Current());
479
480 if (!M->NewParameter(vertex, edge, param, tol)) {
481 tol = BRep_Tool::Tolerance(vertex);
482 param = BRep_Tool::Parameter(vertex,edge);
483 }
484
485
486 TopAbs_Orientation vtxrelat = vertex.Orientation();
487 if (edor == TopAbs_REVERSED) {
488 // Update considere l'edge FORWARD, et le vertex en relatif
489 vtxrelat= TopAbs::Reverse(vtxrelat);
490 }
491// if (result.Orientation() == TopAbs_REVERSED) {
492// vtxrelat= TopAbs::Reverse(vtxrelat);
493// }
494 TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
495 aLocalVertex.Orientation(vtxrelat);
496// B.UpdateVertex(TopoDS::Vertex
497// (myMap(vertex).Oriented(vtxrelat)),
498 B.UpdateVertex(aLocalVertex,
499 param,
500 TopoDS::Edge(result),
501 tol);
502
503 ex.Next();
504 }
505
506 }
507
508 // update flags
509
510 result.Orientable(S.Orientable());
511 result.Closed(S.Closed());
512 result.Infinite(S.Infinite());
513 }
514 else
515 result = S;
516
517 // Set flag of the shape.
518 result.Orientation(ResOr);
519
520 result.Free (S.Free());
521 result.Modified (S.Modified());
522 result.Checked (S.Checked());
523 result.Orientable(S.Orientable());
524 result.Closed (S.Closed());
525 result.Infinite (S.Infinite());
526 result.Convex (S.Convex());
527
528 return rebuild;
529}
530
531