Integration of OCCT 6.5.0 from SVN
[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
6// IFV 04.06.99 - PRO18974 - treatment of INTERNAL shapes.
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
107 // Remise a Null des shapes value, dans le cas ou on applique une autre
108 // modification au shape de depart.
109
110 if (!theIter.Value().IsNull()) {
111 while (theIter.More()) {
112 myMap(theIter.Value()).Nullify();
113 theIter.Next();
114 }
115 theIter.Reset();
116 }
117
118 /*
119 while (theIter.More()) {
120 Rebuild(theIter.Key(),M);
121 theIter.Next();
122 }
123 */
124
125 Rebuild(myShape,M);
126
127 if (myShape.ShapeType() == TopAbs_FACE) {
128 if (myShape.Orientation() == TopAbs_REVERSED) {
129 myMap(myShape).Reverse();
130 }
131 else{
132 myMap(myShape).Orientation(myShape.Orientation());
133 }
134 }
135 else {
136 myMap(myShape).Orientation(myShape.Orientation());
137 }
138
139 // Mise a jour des continuites
140
141 TopTools_IndexedDataMapOfShapeListOfShape theEFMap;
142 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,theEFMap);
143 BRep_Builder B;
144
145/*
146 Standard_Boolean RecomputeTriangles = Standard_False;
147 Standard_Real MaxDeflection = RealFirst();
148 Handle(Poly_Triangulation) Tr;
149 Handle(Poly_Polygon3D) Po;
150 TopLoc_Location Loc;
151*/
152
153 while (theIter.More()) {
154 const TopoDS_Shape& S = theIter.Key();
155/*
156 if (S.ShapeType() == TopAbs_FACE && !S.IsSame(theIter.Value())) {
157 Tr = BRep_Tool::Triangulation(TopoDS::Face(S),Loc);
158 if (!Tr.IsNull()) {
159 RecomputeTriangles = Standard_True;
160 MaxDeflection = Max(MaxDeflection,Tr->Deflection());
161 }
162 }
163 else */ if (S.ShapeType() == TopAbs_EDGE && !S.IsSame(theIter.Value())) {
164 const TopoDS_Edge& edg = TopoDS::Edge(S);
165/*
166 Po = BRep_Tool::Polygon3D(edg,Loc);
167 if (!Po.IsNull()) {
168 RecomputeTriangles = Standard_True;
169 MaxDeflection = Max(MaxDeflection,Po->Deflection());
170 }
171*/
172 TopTools_ListIteratorOfListOfShape it;
173 it.Initialize(theEFMap.FindFromKey(edg));
174 TopoDS_Face F1,F2;
175 while (it.More() && F2.IsNull()) {
176 if (F1.IsNull()) {
177 F1 = TopoDS::Face(it.Value());
178 }
179 else {
180 F2 = TopoDS::Face(it.Value());
181 }
182 it.Next();
183 }
184 if (!F2.IsNull()) {
185 const TopoDS_Edge& newedg = TopoDS::Edge(myMap(edg));
186 const TopoDS_Face& newf1 = TopoDS::Face(myMap(F1));
187 const TopoDS_Face& newf2 = TopoDS::Face(myMap(F2));
188 GeomAbs_Shape Newcont = M->Continuity(edg,F1,F2,newedg,newf1,newf2);
189 if (Newcont > GeomAbs_C0) {
190 B.Continuity(newedg,newf1,newf2,Newcont);
191 }
192 }
193 }
194 theIter.Next();
195 }
196/*
197 if (RecomputeTriangles) {
198 BRepMesh_IncrementalMesh(myMap(myShape),MaxDeflection);
199 }
200*/
201
202 myDone = Standard_True;
203
204}
205
206//=======================================================================
207//function : Put
208//purpose :
209//=======================================================================
210
211void BRepTools_Modifier::Put(const TopoDS_Shape& S)
212{
213 if (!myMap.IsBound(S)) {
214 myMap.Bind(S,TopoDS_Shape());
215 for(TopoDS_Iterator theIterator(S,Standard_False);theIterator.More();theIterator.Next()) {
216
217 Put(theIterator.Value());
218 }
219 }
220}
221
222//=======================================================================
223//function : Rebuild
224//purpose :
225//=======================================================================
226
227Standard_Boolean BRepTools_Modifier::Rebuild
228 (const TopoDS_Shape& S,
229 const Handle(BRepTools_Modification)& M)
230{
231 TopoDS_Shape& result = myMap(S);
232// if (!result.IsNull()) return ! S.IsEqual(result);
233 if (!result.IsNull()) return ! S.IsSame(result);
234 Standard_Boolean rebuild = Standard_False, RevWires = Standard_False;
235 TopAbs_Orientation ResOr = TopAbs_FORWARD;
236 BRep_Builder B;
237 Standard_Real tol;
238 Standard_Boolean No3DCurve = Standard_False; // en fait, si on n`a pas de
239 //modif de geometrie 3d , il faudrait tester l`existence d`une courbe 3d.
240
241 // new geometry ?
242
243 TopAbs_ShapeEnum ts = S.ShapeType();
244 switch (ts) {
245 case TopAbs_FACE:
246 {
247 Standard_Boolean RevFace;
248 Handle(Geom_Surface) surface;
249 TopLoc_Location location;
250 rebuild = M->NewSurface(TopoDS::Face(S),surface,location,tol,
251 RevWires,RevFace);
252 if (rebuild) {
253 B.MakeFace(TopoDS::Face(result),surface,
254 location.Predivided(S.Location()),tol);
255 result.Location(S.Location());
256// result.Orientation(S.Orientation());
257 if (RevFace) {
258 ResOr = TopAbs_REVERSED;
259 }
260 // set specifics flags of a Face
261 B.NaturalRestriction(TopoDS::Face(result),
262 BRep_Tool::NaturalRestriction(TopoDS::Face(S)));
263 }
264 }
265 break;
266
267 case TopAbs_EDGE:
268 {
269 Handle(Geom_Curve) curve;
270 TopLoc_Location location;
271 rebuild = M->NewCurve(TopoDS::Edge(S),curve,location,tol);
272 if (rebuild) {
273 if (curve.IsNull()) {
274 B.MakeEdge(TopoDS::Edge(result));
275 B.Degenerated(TopoDS::Edge(result),
276 BRep_Tool::Degenerated(TopoDS::Edge(S)));
277 B.UpdateEdge(TopoDS::Edge(result),tol); //OCC217
278 No3DCurve = Standard_True;
279 }
280 else {
281 B.MakeEdge(TopoDS::Edge(result),curve,
282 location.Predivided(S.Location()),tol);
283 No3DCurve = Standard_False;
284 }
285 result.Location(S.Location());
286// result.Orientation(S.Orientation());
287
288 // set specifics flags of an Edge
289 B.SameParameter(TopoDS::Edge(result),
290 BRep_Tool::SameParameter(TopoDS::Edge(S)));
291 B.SameRange(TopoDS::Edge(result),
292 BRep_Tool::SameRange(TopoDS::Edge(S)));
293 }
294 }
295 break;
296
297 case TopAbs_VERTEX:
298 {
299 gp_Pnt vtx;
300 rebuild = M->NewPoint(TopoDS::Vertex(S),vtx,tol);
301 if (rebuild) {
302 B.MakeVertex(TopoDS::Vertex(result),vtx,tol);
303 }
304 }
305 break;
306
307 default:
308 {
309 }
310 }
311
312 // rebuild sub-shapes and test new sub-shape ?
313
314 Standard_Boolean newgeom = rebuild;
315
316 TopoDS_Iterator it;
317
318 for (it.Initialize(S, Standard_False); it.More(); it.Next()) {
319 // always call Rebuild
320 Standard_Boolean subrebuilt = Rebuild(it.Value(),M);
321 rebuild = subrebuilt || rebuild ;
322 }
323
324 // make an empty copy
325 if (rebuild && !newgeom) {
326 result = S.EmptyCopied();
327 result.Orientation(TopAbs_FORWARD);
328 }
329
330 // copy the sub-elements
331
332 if (rebuild) {
333 TopAbs_Orientation orient;
334 for (it.Initialize(S,Standard_False); it.More(); it.Next()) {
335 orient = it.Value().Orientation();
336 if (RevWires || myMap(it.Value()).Orientation() == TopAbs_REVERSED) {
337 orient = TopAbs::Reverse(orient);
338 }
339 B.Add(result,myMap(it.Value()).Oriented(orient));
340 }
341
342
343 if (ts == TopAbs_FACE) {
344 // pcurves
345 Handle(Geom2d_Curve) curve2d; //,curve2d1;
346 TopoDS_Face face = TopoDS::Face(S);
347 TopAbs_Orientation fcor = face.Orientation();
348 if(fcor != TopAbs_REVERSED) fcor = TopAbs_FORWARD;
349
350 TopExp_Explorer ex(face.Oriented(fcor),TopAbs_EDGE);
351 for (;ex.More(); ex.Next())
352 {
353 const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
354
355 if (M->NewCurve2d(edge, face,TopoDS::Edge(myMap(ex.Current())),
356 TopoDS::Face(result),curve2d, tol))
357 {
358 // rem dub 16/09/97 : On fait de la topologie constante ou on
359 // n'en fait pas.
360 // On n'en fait pas si CopySurface = 1
361 // Atention, les VRAIES aretes de couture (RealyClosed) le
362 // restent meme si CopySurface est vrai.
363
364 // check that edge contains two pcurves on this surface:
365 // either it is true seam on the current face, or belongs to two faces
366 // built on that same surface (see OCC21772)
367 // Note: this check could be made separate method in BRepTools
368 Standard_Boolean isClosed = Standard_False;
369 if(BRep_Tool::IsClosed(edge,face))
370 {
371 isClosed = ( ! newgeom || BRepTools::IsReallyClosed(edge,face) );
372 if ( ! isClosed )
373 {
374 TopLoc_Location aLoc;
375 TopoDS_Shape resface = (myMap.IsBound(face) ? myMap(face) : face);
376 if(resface.IsNull())
377 resface = face;
378 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(resface), aLoc);
379 // check other faces sharing the same surface
380 TopExp_Explorer aExpF(myShape,TopAbs_FACE);
381 for( ; aExpF.More() && !isClosed; aExpF.Next())
382 {
383 TopoDS_Face anOther = TopoDS::Face(aExpF.Current());
384 if(anOther.IsSame(face))
385 continue;
386 TopoDS_Shape resface2 = (myMap.IsBound(anOther) ? myMap(anOther) : anOther);
387 if(resface2.IsNull())
388 resface2 = anOther;
389 TopLoc_Location anOtherLoc;
390 Handle(Geom_Surface) anOtherSurf =
391 BRep_Tool::Surface(TopoDS::Face(resface2), anOtherLoc);
392 if ( aSurf == anOtherSurf && aLoc.IsEqual (anOtherLoc) )
393 {
394 TopExp_Explorer aExpE(anOther,TopAbs_EDGE);
395 for( ; aExpE.More() && !isClosed ; aExpE.Next())
396 isClosed = edge.IsSame(aExpE.Current());
397 }
398 }
399 }
400 }
401 if (isClosed)
402 {
403 TopoDS_Edge CurE = TopoDS::Edge(myMap(edge));
404 TopoDS_Shape aLocalResult = result;
405 aLocalResult.Orientation(TopAbs_FORWARD);
406 TopoDS_Face CurF = TopoDS::Face(aLocalResult);
407 Handle(Geom2d_Curve) curve2d1, currcurv;
408 Standard_Real f,l;
409 if ((!RevWires && fcor != edge.Orientation()) ||
410 ( RevWires && fcor == edge.Orientation())) {
411 CurE.Orientation(TopAbs_FORWARD);
412 curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
413 if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
414 B.UpdateEdge (CurE, curve2d1, curve2d, CurF, 0.);
415 }
416 else {
417 CurE.Orientation(TopAbs_REVERSED);
418 curve2d1 = BRep_Tool::CurveOnSurface(CurE,CurF,f,l);
419 if (curve2d1.IsNull()) curve2d1 = new Geom2d_Line(gp::OX2d());
420 B.UpdateEdge (CurE, curve2d, curve2d1, CurF, 0.);
421 }
422 currcurv = BRep_Tool::CurveOnSurface(edge,face,f,l);
423 B.Range(edge,f,l);
424 }
425 else {
426 B.UpdateEdge(TopoDS::Edge(myMap(ex.Current())),
427 curve2d,
428 TopoDS::Face(result), 0.);
429 }
430
431 TopLoc_Location theLoc;
432 Standard_Real theF,theL;
433 Handle(Geom_Curve) C3D =
434 BRep_Tool::Curve(TopoDS::Edge(myMap(ex.Current())),
435 theLoc,theF,theL);
436 if (C3D.IsNull()) { // Update vertices
437 Standard_Real param;
438 TopExp_Explorer ex2(edge,TopAbs_VERTEX);
439 while (ex2.More()) {
440 const TopoDS_Vertex& vertex = TopoDS::Vertex(ex2.Current());
441 if (!M->NewParameter(vertex, edge, param, tol)) {
442 tol = BRep_Tool::Tolerance(vertex);
443 param = BRep_Tool::Parameter(vertex,edge);
444 }
445
446 TopAbs_Orientation vtxrelat = vertex.Orientation();
447 if (edge.Orientation() == TopAbs_REVERSED) {
448 // Update considere l'edge FORWARD, et le vertex en relatif
449 vtxrelat= TopAbs::Reverse(vtxrelat);
450 }
451// if (myMap(edge).Orientation() == TopAbs_REVERSED) {
452// vtxrelat= TopAbs::Reverse(vtxrelat);
453// }
454 TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
455 aLocalVertex.Orientation(vtxrelat);
456// B.UpdateVertex(TopoDS::Vertex
457// (myMap(vertex).Oriented(vtxrelat)),
458 B.UpdateVertex(aLocalVertex,
459 param,
460 TopoDS::Edge(myMap(edge)),
461 tol);
462 ex2.Next();
463 }
464 }
465
466 }
467 }
468
469 }
470
471// else if (ts == TopAbs_EDGE) {
472 else if (ts == TopAbs_EDGE && !No3DCurve) {
473 // Vertices
474 Standard_Real param;
475 const TopoDS_Edge& edge = TopoDS::Edge(S);
476 TopAbs_Orientation edor = edge.Orientation();
477 if(edor != TopAbs_REVERSED) edor = TopAbs_FORWARD;
478 TopExp_Explorer ex(edge.Oriented(edor), TopAbs_VERTEX);
479 while (ex.More()) {
480 const TopoDS_Vertex& vertex = TopoDS::Vertex(ex.Current());
481
482 if (!M->NewParameter(vertex, edge, param, tol)) {
483 tol = BRep_Tool::Tolerance(vertex);
484 param = BRep_Tool::Parameter(vertex,edge);
485 }
486
487
488 TopAbs_Orientation vtxrelat = vertex.Orientation();
489 if (edor == TopAbs_REVERSED) {
490 // Update considere l'edge FORWARD, et le vertex en relatif
491 vtxrelat= TopAbs::Reverse(vtxrelat);
492 }
493// if (result.Orientation() == TopAbs_REVERSED) {
494// vtxrelat= TopAbs::Reverse(vtxrelat);
495// }
496 TopoDS_Vertex aLocalVertex = TopoDS::Vertex(myMap(vertex));
497 aLocalVertex.Orientation(vtxrelat);
498// B.UpdateVertex(TopoDS::Vertex
499// (myMap(vertex).Oriented(vtxrelat)),
500 B.UpdateVertex(aLocalVertex,
501 param,
502 TopoDS::Edge(result),
503 tol);
504
505 ex.Next();
506 }
507
508 }
509
510 // update flags
511
512 result.Orientable(S.Orientable());
513 result.Closed(S.Closed());
514 result.Infinite(S.Infinite());
515 }
516 else
517 result = S;
518
519 // Set flag of the shape.
520 result.Orientation(ResOr);
521
522 result.Free (S.Free());
523 result.Modified (S.Modified());
524 result.Checked (S.Checked());
525 result.Orientable(S.Orientable());
526 result.Closed (S.Closed());
527 result.Infinite (S.Infinite());
528 result.Convex (S.Convex());
529
530 return rebuild;
531}
532
533