Commit | Line | Data |
---|---|---|
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 | ||
51 | BRepTools_Modifier::BRepTools_Modifier ():myDone(Standard_False) | |
52 | {} | |
53 | ||
54 | //======================================================================= | |
55 | //function : BRepTools_Modifier | |
56 | //purpose : | |
57 | //======================================================================= | |
58 | ||
59 | BRepTools_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 | ||
71 | BRepTools_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 | ||
86 | void 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 | ||
100 | void 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 | ||
210 | void 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 | ||
226 | Standard_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 |