1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 // This file is part of Open CASCADE Technology software library.
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
19 #include <BOPAlgo_Builder.hxx>
20 #include <BOPDS_DS.hxx>
21 #include <BOPTools_AlgoTools.hxx>
23 #include <TopoDS_Shape.hxx>
24 #include <TopTools_ListOfShape.hxx>
25 #include <TopTools_MapOfShape.hxx>
27 //=======================================================================
28 //function : LocGenerated
30 //=======================================================================
31 const TopTools_ListOfShape& BOPAlgo_Builder::LocGenerated
32 (const TopoDS_Shape& theS)
34 // The rules for Generated shapes are these:
35 // 1. The EDGE may be generated from the FACES as an intersection edge;
36 // 2. The VERTEX may be generated from the EDGES and FACES as an intersection vertex.
38 // The list of generated elements will contain only those which are contained
39 // in the result of the operation.
46 // Only EDGES and FACES should be considered
47 TopAbs_ShapeEnum aType = theS.ShapeType();
48 if (aType != TopAbs_EDGE && aType != TopAbs_FACE)
52 // Check that DS contains the shape, i.e. it is from the arguments of the operation
53 Standard_Integer nS = myDS->Index(theS);
58 // Check that the shape has participated in any intersections
59 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nS);
60 if (!aSI.HasReference())
64 // Analyze all types of Interferences which can produce
65 // new vertices - Edge/Edge and Edge/Face
66 BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
67 BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
69 // Fence map to avoid duplicates in the list of Generated;
70 TColStd_MapOfInteger aMFence;
72 // Analyze each interference and find those in which the given shape has participated
74 // No need to analyze Edge/Edge interferences for the shapes of type FACE
75 Standard_Boolean isFace = (aType == TopAbs_FACE);
77 for (Standard_Integer k = (isFace ? 1 : 0); k < 2; ++k)
79 Standard_Integer aNbLines = !k ? aEEs.Length() : aEFs.Length();
80 for (Standard_Integer i = 0; i < aNbLines; ++i)
82 BOPDS_Interf *aInt = !k ? (BOPDS_Interf*)(&aEEs(i)) : (BOPDS_Interf*)(&aEFs(i));
83 if (!aInt->HasIndexNew())
84 // No new vertices created
87 if (!aInt->Contains(nS))
90 Standard_Integer nVNew = aInt->IndexNew();
91 myDS->HasShapeSD(nVNew, nVNew);
92 if (!aMFence.Add(nVNew))
96 const TopoDS_Shape& aVNew = myDS->Shape(nVNew);
98 // Check that the result shape contains vertex
99 if (myMapShape.Contains(aVNew))
100 // Save the vertex as generated
101 myHistShapes.Append(aVNew);
108 // For the FACE it is also necessary to collect all
109 // section elements created in FACE/FACE interferences.
110 // This information is available in the FaceInfo structure.
111 const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nS);
113 // Section edges of the face
114 const BOPDS_IndexedMapOfPaveBlock& aMPBSc = aFI.PaveBlocksSc();
115 // Save section edges contained in the result shape
116 Standard_Integer aNb = aMPBSc.Extent();
117 for (Standard_Integer i = 1; i <= aNb; ++i)
119 const TopoDS_Shape& aENew = myDS->Shape(aMPBSc(i)->Edge());
120 if (myMapShape.Contains(aENew))
121 myHistShapes.Append(aENew);
124 // Section vertices of the face
125 const TColStd_MapOfInteger& aMVSc = aFI.VerticesSc();
126 // Save section vertices contained in the result shape
127 TColStd_MapOfInteger::Iterator aItM(aMVSc);
128 for (; aItM.More(); aItM.Next())
130 const TopoDS_Shape& aVNew = myDS->Shape(aItM.Value());
131 if (myMapShape.Contains(aVNew))
132 myHistShapes.Append(aVNew);
137 //=======================================================================
138 //function : LocModified
140 //=======================================================================
141 const TopTools_ListOfShape* BOPAlgo_Builder::LocModified(const TopoDS_Shape& theS)
143 return myImages.Seek(theS);
145 //=======================================================================
146 //function : PrepareHistory
148 //=======================================================================
149 void BOPAlgo_Builder::PrepareHistory()
154 // Initializing history tool
155 myHistory = new BRepTools_History;
157 // Map the result shape
159 TopExp::MapShapes(myShape, myMapShape);
161 // Among all input shapes find:
162 // - Shapes that have been modified (split). Add the splits kept in the result
163 // shape as Modified from the shape;
164 // - Shapes that have created new geometries (i.e. generated new shapes). Add
165 // the generated elements kept in the result shape as Generated from the shape;
166 // - Shapes that have no trace in the result shape. Add them as Deleted
167 // during the operation.
168 Standard_Integer aNbS = myDS->NbSourceShapes();
169 for (Standard_Integer i = 0; i < aNbS; ++i)
171 const TopoDS_Shape& aS = myDS->Shape(i);
173 // Check if History information is available for this kind of shape.
174 if (!BRepTools_History::IsSupportedType(aS))
177 Standard_Boolean isModified = Standard_False;
179 // Check if the shape has any splits
180 const TopTools_ListOfShape* pLSp = LocModified(aS);
183 // Find all splits of the shape which are kept in the result
184 TopTools_ListIteratorOfListOfShape aIt(*pLSp);
185 for (; aIt.More(); aIt.Next())
187 TopoDS_Shape aSp = aIt.Value();
188 // Check if the result shape contains the split
189 if (myMapShape.Contains(aSp))
191 // Add modified shape with proper orientation
192 TopAbs_ShapeEnum aType = aSp.ShapeType();
193 if (aType == TopAbs_VERTEX || aType == TopAbs_SOLID)
194 aSp.Orientation(aS.Orientation());
195 else if (BOPTools_AlgoTools::IsSplitToReverse(aSp, aS, myContext))
198 myHistory->AddModified(aS, aSp);
199 isModified = Standard_True;
204 // Check if the shape has Generated elements
205 const TopTools_ListOfShape& aGenShapes = LocGenerated(aS);
206 TopTools_ListIteratorOfListOfShape aIt(aGenShapes);
207 for (; aIt.More(); aIt.Next())
209 const TopoDS_Shape& aG = aIt.Value();
210 if (myMapShape.Contains(aG))
211 myHistory->AddGenerated(aS, aG);
214 // Check if the shape has been deleted, i.e. it is not contained in the result
215 // and has no Modified shapes.
216 if (!isModified && !myMapShape.Contains(aS))
217 myHistory->Remove(aS);