1 // File: QANewModTopOpe_Glue_solid.cxx
2 // Created: Sat May 5 09:55:59 2001
3 // Author: Sergey KHROMOV <skv@nnov.matra-dtv.fr>
4 // Copyright: SAMTECH S.A. 2001
6 const static char sccsid[] = "@(#) QANewModTopOpe_Glue_SDFaces.cxx 4.2-3, 01/07/04@(#)";
8 // Lastly modified by :
9 // +---------------------------------------------------------------------------+
10 // ! pat ! fix for 4086 ! 01/07/04! 4.2-3!
11 // ! skv ! Adaptation to OCC version 5.0 ! 6-05-2003! 3.0-00-2!
12 // +---------------------------------------------------------------------------+
15 #include <QANewModTopOpe_Glue.ixx>
16 #include <TopExp_Explorer.hxx>
18 #include <TopTools_ListIteratorOfListOfShape.hxx>
19 #include <TopTools_ListOfShape.hxx>
20 #include <TopoDS_Compound.hxx>
21 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
22 #include <TopTools_MapOfShape.hxx>
23 #include <TopTools_MapIteratorOfMapOfShape.hxx>
25 #include <QANewModTopOpe_Tools.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <Geom_TrimmedCurve.hxx>
29 #include <GeomProjLib.hxx>
30 #include <Precision.hxx>
31 #include <BRepAdaptor_Surface.hxx>
33 static Standard_Boolean isAnalitic(const TopoDS_Shape &theShape)
35 if (theShape.ShapeType() != TopAbs_FACE)
36 return Standard_False;
38 TopoDS_Face aFace = TopoDS::Face(theShape);
39 BRepAdaptor_Surface aSurf(aFace);
40 Standard_Boolean isAna = Standard_False;
42 switch (aSurf.GetType()) {
44 case GeomAbs_Cylinder :
48 isAna = Standard_True;
51 isAna = Standard_False;
57 static void DoPCurveOnF(const TopoDS_Edge &theEdge, const TopoDS_Face &theFace)
59 BRep_Builder aBuilder;
60 TopLoc_Location aCLoc;
61 TopLoc_Location aSLoc;
64 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aCLoc, aF, aL);
65 Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, aF, aL);
66 Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace, aSLoc);
67 TopLoc_Location aCTLoc = aSLoc.Inverted().Multiplied(aCLoc);
69 aTrCurve->Transform(aCTLoc.Transformation());
71 Handle(Geom2d_Curve) aCurve2d = GeomProjLib::Curve2d (aTrCurve, aSurface);
73 aBuilder.UpdateEdge(theEdge, aCurve2d, aSurface,
74 aSLoc, Precision::Confusion());
77 static TopoDS_Face GetAdjacentFace
78 (const TopoDS_Shape &theEdge,
79 const TopoDS_Shape &theFace,
80 const TopTools_IndexedDataMapOfShapeListOfShape &theAncMap)
84 if (theAncMap.Contains(theEdge)) {
85 const TopTools_ListOfShape &aLOfFaces =
86 theAncMap.FindFromKey(theEdge);
87 TopTools_ListIteratorOfListOfShape anIter(aLOfFaces);
89 for (; anIter.More(); anIter.Next()) {
90 const TopoDS_Shape &aLocalFace = anIter.Value();
92 if (!theFace.IsSame(aLocalFace)) {
93 aFace = TopoDS::Face(aLocalFace);
102 //=======================================================================
103 //function : SubstitudeSDFaces
105 //=======================================================================
107 Standard_Boolean QANewModTopOpe_Glue::SubstitudeSDFaces
108 (const TopoDS_Shape &theFirstSDFace,
109 const TopoDS_Shape &theSecondSDFace,
110 TopoDS_Shape &theNewSolid1,
111 TopoDS_Shape &theNewSolid2,
112 TopTools_DataMapOfShapeListOfShape &theMapOfChangedFaces)
114 // If the first face is already splited, we use its splits
115 // to recursively call this function.
116 if (theMapOfChangedFaces.IsBound(theFirstSDFace)) {
117 const TopTools_ListOfShape &aLocalList =
118 theMapOfChangedFaces(theFirstSDFace);
119 TopTools_ListIteratorOfListOfShape anIter(aLocalList);
121 for (;anIter.More(); anIter.Next()) {
122 const TopoDS_Shape &aNewShape = anIter.Value();
123 if (!SubstitudeSDFaces(aNewShape, theSecondSDFace,
124 theNewSolid1, theNewSolid2,
125 theMapOfChangedFaces))
126 return Standard_False;
128 return Standard_True;
131 // If the second face is already splited, we use its splits
132 // to recursively call this function.
133 if (theMapOfChangedFaces.IsBound(theSecondSDFace)) {
134 const TopTools_ListOfShape &aLocalList =
135 theMapOfChangedFaces(theSecondSDFace);
136 TopTools_ListIteratorOfListOfShape anIter(aLocalList);
138 for (;anIter.More(); anIter.Next()) {
139 const TopoDS_Shape &aNewShape = anIter.Value();
140 if (!SubstitudeSDFaces(theFirstSDFace, aNewShape,
141 theNewSolid1, theNewSolid2,
142 theMapOfChangedFaces))
143 return Standard_False;
145 return Standard_True;
149 // If neither the first face nor the second one were
150 // splited before, we begin calculation:
151 TopTools_IndexedDataMapOfShapeListOfShape aHistory;
152 Standard_Boolean isCommonFound;
154 if (!QANewModTopOpe_Tools::BoolOpe(theFirstSDFace.Oriented(TopAbs_FORWARD),
155 theSecondSDFace.Oriented(TopAbs_FORWARD),
156 isCommonFound, aHistory))
157 return Standard_False;
160 return Standard_True;
162 TopTools_IndexedDataMapOfShapeListOfShape anAncMap1;
163 TopTools_IndexedDataMapOfShapeListOfShape anAncMap2;
165 TopExp::MapShapesAndAncestors(theNewSolid1, TopAbs_EDGE,
166 TopAbs_FACE, anAncMap1);
167 TopExp::MapShapesAndAncestors(theNewSolid2, TopAbs_EDGE,
168 TopAbs_FACE, anAncMap2);
170 // Creation of a compound of old solids.
171 // The substitution operation will be built with this
173 BRep_Builder aBuilder;
174 TopoDS_Compound aCompound;
176 aBuilder.MakeCompound(aCompound);
177 aBuilder.Add(aCompound, theNewSolid1);
178 aBuilder.Add(aCompound, theNewSolid2);
180 // Substitution of updated sub-shapes of the first solid.
181 BRepTools_Substitution aSubstTool;
182 Standard_Integer aNbModifShape = aHistory.Extent();
185 for (i = 1; i <= aNbModifShape; i++) {
186 TopTools_ListOfShape aModifShapes;
187 const TopoDS_Shape &anAncestor = aHistory.FindKey(i);
188 TopTools_ListIteratorOfListOfShape anIter(aHistory.FindFromIndex(i));
190 if (anAncestor.IsSame(theSecondSDFace)) {
191 for (; anIter.More(); anIter.Next())
192 aModifShapes.Append(anIter.Value());
194 for (; anIter.More(); anIter.Next())
195 aModifShapes.Append(anIter.Value().Oriented(TopAbs_FORWARD));
198 if (anAncestor.ShapeType() == TopAbs_EDGE) {
199 // Check if the edges from common contain pcurves on both shapes.
200 // If they do not, create them.
201 TopoDS_Edge anAncEdge = TopoDS::Edge(anAncestor);
203 if (anAncMap1.Contains(anAncestor)) {
204 TopoDS_Face aFace = GetAdjacentFace(anAncestor, theFirstSDFace,
206 if(!aFace.IsNull()) {//added to fix 4086
207 Standard_Real aFirst;
210 anIter.Initialize(aHistory.FindFromIndex(i));
211 for (; anIter.More(); anIter.Next()) {
212 TopoDS_Edge aSplit = TopoDS::Edge(anIter.Value());
213 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface
214 (aSplit, aFace, aFirst, aLast);
216 if (aPCurve.IsNull())
217 DoPCurveOnF(aSplit, aFace);
222 if (anAncMap2.Contains(anAncestor)) {
223 TopoDS_Face aFace = GetAdjacentFace(anAncestor, theSecondSDFace,
225 if(!aFace.IsNull()) {//added to fix 4086
226 Standard_Real aFirst;
229 anIter.Initialize(aHistory.FindFromIndex(i));
230 for (; anIter.More(); anIter.Next()) {
231 TopoDS_Edge aSplit = TopoDS::Edge(anIter.Value());
232 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface
233 (aSplit, aFace, aFirst, aLast);
235 if (aPCurve.IsNull())
236 DoPCurveOnF(aSplit, aFace);
242 //--------------------------------------------------------------
243 if (!myMapModif.IsBound(anAncestor))
244 myMapModif.Bind(anAncestor, aModifShapes);
245 //--------------------------------------------------------------
247 aSubstTool.Substitute(anAncestor, aModifShapes);
250 aSubstTool.Build(aCompound);
252 // Update the map theMapOfChangedFaces and
253 // obtain a new solid from the first one.
254 if (aSubstTool.IsCopied(theNewSolid1)) {
255 // Add changed faces of the first solid to theMapOfChangedFaces:
256 TopExp_Explorer anExp(theNewSolid1, TopAbs_FACE);
257 for (; anExp.More(); anExp.Next()) {
258 // For each face from solid
259 const TopoDS_Shape &aFace = anExp.Current();
261 if (aSubstTool.IsCopied(aFace)) {
262 const TopTools_ListOfShape &aList = aSubstTool.Copy(aFace);
264 TopTools_ListOfShape aNewList;
265 if (!theMapOfChangedFaces.IsBound(aFace))
266 theMapOfChangedFaces.Bind(aFace, aNewList);
268 TopTools_ListIteratorOfListOfShape anIter(aList);
269 for (; anIter.More(); anIter.Next()) {
270 TopoDS_Shape aLocalFace = anIter.Value();
272 if (aSubstTool.IsCopied(aLocalFace))
273 aLocalFace = aSubstTool.Copy(aLocalFace).First();
275 theMapOfChangedFaces(aFace).Append(aLocalFace);
279 // Obtain a new solid.
280 theNewSolid1 = aSubstTool.Copy(theNewSolid1).First();
283 // Update the map theMapOfChangedFaces and
284 // obtain a new solid from the second one.
285 if (aSubstTool.IsCopied(theNewSolid2)) {
286 // Add changed faces of the second solid to theMapOfChangedFaces:
287 TopExp_Explorer anExp(theNewSolid2, TopAbs_FACE);
288 for (; anExp.More(); anExp.Next()) {
289 // For each face from solid
290 const TopoDS_Shape &aFace = anExp.Current();
292 if (aSubstTool.IsCopied(aFace)) {
293 const TopTools_ListOfShape &aList = aSubstTool.Copy(aFace);
295 TopTools_ListOfShape aNewList;
296 if (!theMapOfChangedFaces.IsBound(aFace))
297 theMapOfChangedFaces.Bind(aFace, aNewList);
299 TopTools_ListIteratorOfListOfShape anIter(aList);
300 for (; anIter.More(); anIter.Next()) {
301 TopoDS_Shape aLocalFace = anIter.Value();
303 if (aSubstTool.IsCopied(aLocalFace))
304 aLocalFace = aSubstTool.Copy(aLocalFace).First();
306 theMapOfChangedFaces(aFace).Append(aLocalFace);
310 // Obtain a new solid.
311 theNewSolid2 = aSubstTool.Copy(theNewSolid2).First();
314 return Standard_True;
317 //=======================================================================
318 //function : PerformSolidSolid
320 //=======================================================================
323 QANewModTopOpe_Glue::PerformSDFaces()
325 TopExp_Explorer anExp;
326 TopoDS_Shape aS1, aS2;
327 Standard_Boolean aWire1 = Standard_False, aWire2 = Standard_False;
328 anExp.Init(myS1, TopAbs_WIRE, TopAbs_FACE);
331 aWire1 = Standard_True;
334 anExp.Init(myS1, TopAbs_EDGE, TopAbs_WIRE);
337 aWire1 = Standard_True;
341 anExp.Init(myS2, TopAbs_WIRE, TopAbs_FACE);
344 aWire2 = Standard_True;
347 anExp.Init(myS2, TopAbs_EDGE, TopAbs_WIRE);
350 aWire2 = Standard_True;
357 aBld.MakeCompound(TopoDS::Compound(myS1));
358 anExp.Init(aS1, TopAbs_COMPSOLID);
359 for(; anExp.More(); anExp.Next()) {
360 aBld.Add(myS1, anExp.Current());
363 anExp.Init(aS1, TopAbs_SOLID, TopAbs_COMPSOLID);
364 for(; anExp.More(); anExp.Next()) {
365 aBld.Add(myS1, anExp.Current());
368 anExp.Init(aS1, TopAbs_SHELL, TopAbs_SOLID);
369 for(; anExp.More(); anExp.Next()) {
370 aBld.Add(myS1, anExp.Current());
373 anExp.Init(aS1, TopAbs_FACE, TopAbs_SHELL);
374 for(; anExp.More(); anExp.Next()) {
375 aBld.Add(myS1, anExp.Current());
383 aBld.MakeCompound(TopoDS::Compound(myS2));
384 anExp.Init(aS2, TopAbs_COMPSOLID);
385 for(; anExp.More(); anExp.Next()) {
386 aBld.Add(myS2, anExp.Current());
389 anExp.Init(aS2, TopAbs_SOLID, TopAbs_COMPSOLID);
390 for(; anExp.More(); anExp.Next()) {
391 aBld.Add(myS2, anExp.Current());
394 anExp.Init(aS2, TopAbs_SHELL, TopAbs_SOLID);
395 for(; anExp.More(); anExp.Next()) {
396 aBld.Add(myS2, anExp.Current());
399 anExp.Init(aS2, TopAbs_FACE, TopAbs_SHELL);
400 for(; anExp.More(); anExp.Next()) {
401 aBld.Add(myS2, anExp.Current());
406 BRepAlgoAPI_BooleanOperation::Build();
407 if (!BuilderCanWork())
410 if(aWire1) myS1 = aS1;
411 if(aWire2) myS2 = aS2;
415 TopoDS_Shape aNewShape1 = myS1;
416 TopoDS_Shape aNewShape2 = myS2;
417 TopTools_DataMapOfShapeListOfShape theMapOfChangedFaces;
419 Standard_Boolean aHasSDF = Standard_False;
420 anExp.Init(myS1, TopAbs_FACE);
421 for (; anExp.More(); anExp.Next()) {
422 TopoDS_Shape aFirstFace = anExp.Current();
424 if (!isAnalitic(aFirstFace))
427 if (QANewModTopOpe_Tools::HasSameDomain(myDSFiller, aFirstFace)) {
429 if(!aHasSDF) aHasSDF = Standard_True;
431 TopTools_ListOfShape aLOfSDFace;
432 TopTools_ListIteratorOfListOfShape anIter;
434 QANewModTopOpe_Tools::SameDomain(myDSFiller, aFirstFace, aLOfSDFace);
435 anIter.Initialize(aLOfSDFace);
437 for(; anIter.More(); anIter.Next()) {
438 TopoDS_Shape aSecondFace = anIter.Value();
440 if (!isAnalitic(aSecondFace))
443 if (!SubstitudeSDFaces(aFirstFace, aSecondFace,
444 aNewShape1, aNewShape2,
445 theMapOfChangedFaces))
451 if(myS1.IsSame(aNewShape1) && myS2.IsSame(aNewShape2)) return;
454 BRep_Builder aBuilder;
456 // aBuilder.MakeCompSolid(TopoDS::CompSolid(myShape));
457 aBuilder.MakeCompound(TopoDS::Compound(myShape));
459 aBuilder.Add(myShape, aNewShape1);
460 aBuilder.Add(myShape, aNewShape2);
462 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape anIter(theMapOfChangedFaces);
463 for(; anIter.More(); anIter.Next()) {
464 myMapModif.Bind(anIter.Key(), anIter.Value());
467 //--------------- creation myMapGener for common faces
469 TopExp_Explorer anExp1, anExp2;
470 TopTools_MapOfShape aM;
471 anExp1.Init(aNewShape1, TopAbs_FACE);
472 for(; anExp1.More(); anExp1.Next()) {
473 const TopoDS_Shape& aF1 = anExp1.Current();
474 anExp2.Init(aNewShape2, TopAbs_FACE);
475 for(; anExp2.More(); anExp2.Next()) {
476 const TopoDS_Shape& aF2 = anExp2.Current();
477 if(aF1.IsSame(aF2)) {
483 anIter.Initialize(myMapModif);
484 TopTools_ListIteratorOfListOfShape anI1;
485 TopTools_MapIteratorOfMapOfShape anI2;
486 for(; anIter.More(); anIter.Next()) {
487 const TopoDS_Shape& aS = anIter.Key();
488 if(aS.ShapeType() == TopAbs_FACE) {
489 anI1.Initialize(anIter.Value());
490 for(; anI1.More(); anI1.Next()) {
491 const TopoDS_Shape& aSS1 = anI1.Value();
493 for(; anI2.More(); anI2.Next()) {
494 const TopoDS_Shape& aSS2 = anI2.Key();
495 if(aSS1.IsSame(aSS2)) {
496 if(!myMapGener.IsBound(aS)) {
497 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aS, TopTools_ListOfShape());
498 TopTools_ListOfShape aListOfShape1;
499 myMapGener.Bind(aS, aListOfShape1);
501 myMapGener(aS).Append(aSS1);
502 myMapModif(aS).Remove(anI1);
505 if(!anI1.More()) break;
509 // if(anIter.Value().Extent() == 0) myMapModif.UnBind(aS);
513 //--------------- creation myMapGener for common edges
516 anExp1.Init(aNewShape1, TopAbs_EDGE);
517 for(; anExp1.More(); anExp1.Next()) {
518 const TopoDS_Shape& anE1 = anExp1.Current();
519 if(aM.Contains(anE1)) continue;
520 anExp2.Init(aNewShape2, TopAbs_EDGE);
521 for(; anExp2.More(); anExp2.Next()) {
522 const TopoDS_Shape& anE2 = anExp2.Current();
523 if(aM.Contains(anE2)) continue;
524 if(anE1.IsSame(anE2)) {
530 anIter.Initialize(myMapModif);
531 TopTools_MapOfShape aComVerMap;
532 TopTools_MapOfShape aLocVerMap;
534 anExp1.Init(myS1, TopAbs_VERTEX);
535 for(; anExp1.More(); anExp1.Next()) aComVerMap.Add(anExp1.Current());
536 anExp1.Init(myS2, TopAbs_VERTEX);
537 for(; anExp1.More(); anExp1.Next()) aComVerMap.Add(anExp1.Current());
539 for(; anIter.More(); anIter.Next()) {
540 const TopoDS_Shape& aS = anIter.Key();
541 if(aS.ShapeType() == TopAbs_EDGE) {
543 anI1.Initialize(anIter.Value());
544 for(; anI1.More(); anI1.Next()) {
545 const TopoDS_Shape& aSS1 = anI1.Value();
547 for(; anI2.More(); anI2.Next()) {
548 const TopoDS_Shape& aSS2 = anI2.Key();
549 if(aSS1.IsSame(aSS2)) {
550 if(!aS.IsSame(aSS1)) {
551 if(!myMapGener.IsBound(aS)) {
552 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aS, TopTools_ListOfShape());
553 TopTools_ListOfShape aListOfShape2;
554 myMapGener.Bind(aS, aListOfShape2);
556 myMapGener(aS).Append(aSS1);
557 TopoDS_Vertex aV1, aV2;
558 TopExp::Vertices(TopoDS::Edge(aSS1), aV1, aV2);
559 if(!aComVerMap.Contains(aV1)) {
560 if(aLocVerMap.Add(aV1)) {
561 myMapGener(aS).Append(aV1);
564 if(!aComVerMap.Contains(aV2)) {
565 if(aLocVerMap.Add(aV2)) {
566 myMapGener(aS).Append(aV2);
569 myMapModif(aS).Remove(anI1);
572 myMapModif.UnBind(aS);
576 if(!anI1.More()) break;
580 // if(anIter.Value().Extent() == 0) myMapModif.UnBind(aS);
585 anExp1.Init(myShape, TopAbs_VERTEX);
586 for(; anExp1.More(); anExp1.Next()) {
587 const TopoDS_Shape& aV = anExp1.Current();
588 aComVerMap.Remove(aV);
591 anI2.Initialize(aComVerMap);
592 for(; anI2.More(); anI2.Next()) {
593 // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(anI2.Key(), TopTools_ListOfShape());
594 TopTools_ListOfShape aListOfShape3;
595 myMapModif.Bind(anI2.Key(), aListOfShape3);
607 // Copyright SAMTECH ..........................................Version 3.0-00
608 // Lastly modified by : pat Date : 01/07/04
610 // File history synopsis (creation,modification,correction)
611 // +---------------------------------------------------------------------------+
612 // ! Developer ! Comments ! Date ! Version !
613 // +-----------!-----------------------------------------!----------!----------+
614 // ! skv ! Creation ! 5-05-2001! 3.0-00-3!
615 // ! skv ! Adaptation to OCC version 5.0 ! 6-05-2003! 3.0-00-2!
616 // ! vladimir ! adaptation to CAS 5.0 ! 07/01/03! 4.0-2!
617 // ! pat ! fix for 4086 ! 01/07/04! 4.2-3!
618 // +---------------------------------------------------------------------------+