1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
18 #include <BOPTools_RoughShapeIntersector.ixx>
20 #include <TopExp_Explorer.hxx>
21 #include <TColStd_MapOfInteger.hxx>
22 #include <TColStd_ListIteratorOfListOfInteger.hxx>
23 #include <TColStd_Array1OfListOfInteger.hxx>
24 #include <BooleanOperations_ShapesDataStructure.hxx>
25 #include <Bnd_Box.hxx>
27 static Standard_Integer TypeToIndex(const TopAbs_ShapeEnum& theType);
29 static Bnd_Box GetBoxEnlargedBySubShape(const Standard_Integer theIndex,
30 const BooleanOperations_PShapesDataStructure& PDS);
33 // =============================================================================================
34 // function: Constructor
35 // =============================================================================================
36 BOPTools_RoughShapeIntersector::BOPTools_RoughShapeIntersector(const BooleanOperations_PShapesDataStructure& PDS)
38 myIsDone(Standard_False)
43 // =============================================================================================
45 // =============================================================================================
46 void BOPTools_RoughShapeIntersector::Perform()
48 myIsDone = Standard_True;
52 // check flag myIsDone after Prepare() function
55 TColStd_ListOfInteger thelist;
56 TColStd_Array1OfListOfInteger aSortedByTypeShapes1(TypeToIndex(TopAbs_COMPOUND), TypeToIndex(TopAbs_VERTEX));
57 aSortedByTypeShapes1.Init(thelist);
59 TColStd_ListOfInteger thelist1;
60 TColStd_Array1OfListOfInteger aSortedByTypeShapes2(TypeToIndex(TopAbs_COMPOUND), TypeToIndex(TopAbs_VERTEX));
61 aSortedByTypeShapes2.Init(thelist1);
63 Standard_Integer k = 0;
65 for(k = myTableOfStatus->LowerRow(); k <= myTableOfStatus->UpperRow(); k++) {
66 aSortedByTypeShapes1(TypeToIndex(myPDS->GetShapeType(k))).Append(k);
69 for(k = myTableOfStatus->LowerCol(); k <= myTableOfStatus->UpperCol(); k++) {
70 aSortedByTypeShapes2(TypeToIndex(myPDS->GetShapeType(k))).Append(k);
74 Standard_Integer aStartIndex = TypeToIndex(TopAbs_COMPOUND);
75 Standard_Integer anEndIndex = TypeToIndex(TopAbs_VERTEX);
77 for(Standard_Integer index1 = aStartIndex; index1 <= anEndIndex; index1++) {
79 if(aSortedByTypeShapes1(index1).IsEmpty())
82 for(Standard_Integer index2 = aStartIndex; index2 <= anEndIndex; index2++) {
83 if(aSortedByTypeShapes2(index2).IsEmpty())
86 TColStd_ListIteratorOfListOfInteger anIt1;
87 TColStd_ListIteratorOfListOfInteger anIt2;
89 for(anIt1.Initialize(aSortedByTypeShapes1.Value(index1)); anIt1.More(); anIt1.Next()) {
90 for(anIt2.Initialize(aSortedByTypeShapes2.Value(index2)); anIt2.More(); anIt2.Next()) {
93 BOPTools_IntersectionStatus aStatus = myTableOfStatus->Value(anIt1.Value(), anIt2.Value());
95 if(aStatus != BOPTools_UNKNOWN && aStatus != BOPTools_BOUNDINGBOXOFSUBSHAPESINTERSECTED)
98 const Bnd_Box& B1 = myBoundingBoxes->Value(anIt1.Value());
99 const Bnd_Box& B2 = myBoundingBoxes->Value(anIt2.Value());
101 BOPTools_IntersectionStatus aNewValue = BOPTools_BOUNDINGBOXINTERSECTED;
104 aNewValue = BOPTools_NONINTERSECTED;
106 PropagateForSuccessors1(anIt1.Value(), anIt2.Value(), aNewValue);
110 aNewValue = BOPTools_BOUNDINGBOXINTERSECTED;
111 const Bnd_Box& BB1 = myPDS->GetBoundingBox(anIt1.Value());
112 const Bnd_Box& BB2 = myPDS->GetBoundingBox(anIt2.Value());
115 aNewValue = BOPTools_BOUNDINGBOXOFSUBSHAPESINTERSECTED;
118 // It is important to place this line after Propagation
119 myTableOfStatus->ChangeValue(anIt1.Value(), anIt2.Value()) = aNewValue;
126 // =============================================================================================
127 // function: TableOfStatus
128 // =============================================================================================
129 const Handle(BOPTools_HArray2OfIntersectionStatus)& BOPTools_RoughShapeIntersector::TableOfStatus() const
131 return myTableOfStatus;
134 // =============================================================================================
136 // =============================================================================================
137 void BOPTools_RoughShapeIntersector::Prepare()
139 myIsDone = Standard_False;
141 if(!myTableOfStatus.IsNull() &&
143 (myTableOfStatus->LowerRow() == 1) &&
144 (myTableOfStatus->UpperRow() == myPDS->NumberOfShapesOfTheObject()) &&
145 (myTableOfStatus->LowerCol() == myPDS->NumberOfShapesOfTheObject() + 1) &&
146 (myTableOfStatus->UpperCol() == myPDS->NumberOfShapesOfTheObject() + myPDS->NumberOfShapesOfTheTool())) {
147 myIsDone = Standard_True;
151 Standard_Integer firstlowerindex = 1;
152 Standard_Integer firstupperindex = myPDS->NumberOfShapesOfTheObject();
153 Standard_Integer secondlowerindex = myPDS->NumberOfShapesOfTheObject() + 1;
154 Standard_Integer secondupperindex = myPDS->NumberOfShapesOfTheTool() + myPDS->NumberOfShapesOfTheObject();
155 myTableOfStatus = new BOPTools_HArray2OfIntersectionStatus(firstlowerindex, firstupperindex,
156 secondlowerindex, secondupperindex);
157 myIsDone = Standard_True;
163 myTableOfStatus->Init(BOPTools_UNKNOWN);
165 myBoundingBoxes = new Bnd_HArray1OfBox(1, myPDS->NumberOfSourceShapes());
167 for(Standard_Integer i = 1; i <= myPDS->NumberOfSourceShapes(); i++) {
168 const Bnd_Box& aBox = GetBoxEnlargedBySubShape(i, myPDS);
169 myBoundingBoxes->SetValue(i, aBox);
173 // =============================================================================================
175 // =============================================================================================
176 Standard_Boolean BOPTools_RoughShapeIntersector::IsDone() const
181 // =============================================================================================
182 // function: PropagateForSuccessors1
183 // =============================================================================================
184 void BOPTools_RoughShapeIntersector::PropagateForSuccessors1(const Standard_Integer AncestorsIndex1,
185 const Standard_Integer AncestorsIndex2,
186 const BOPTools_IntersectionStatus theStatus)
188 if(myTableOfStatus->Value(AncestorsIndex1, AncestorsIndex2) != BOPTools_UNKNOWN)
191 myTableOfStatus->ChangeValue(AncestorsIndex1, AncestorsIndex2) = theStatus;
193 PropagateForSuccessors2(AncestorsIndex1, AncestorsIndex2, theStatus);
194 Standard_Integer i = 1;
196 for(i = 1; i <= myPDS->NumberOfSuccessors(AncestorsIndex1); i++) {
197 Standard_Integer asuccessor1 = myPDS->GetSuccessor(AncestorsIndex1, i);
198 PropagateForSuccessors1(asuccessor1, AncestorsIndex2, theStatus);
202 // =============================================================================================
203 // function: PropagateForSuccessors2
204 // =============================================================================================
205 void BOPTools_RoughShapeIntersector::PropagateForSuccessors2(const Standard_Integer AncestorsIndex1,
206 const Standard_Integer AncestorsIndex2,
207 const BOPTools_IntersectionStatus theStatus)
209 for(Standard_Integer j = 1; j <= myPDS->NumberOfSuccessors(AncestorsIndex2); j++) {
210 Standard_Integer asuccessor2 = myPDS->GetSuccessor(AncestorsIndex2, j);
212 if(myTableOfStatus->Value(AncestorsIndex1, asuccessor2) == BOPTools_UNKNOWN) {
213 myTableOfStatus->ChangeValue(AncestorsIndex1, asuccessor2) = theStatus;
215 PropagateForSuccessors2(AncestorsIndex1, asuccessor2, theStatus);
220 // =============================================================================================
221 // function: TypeToIndex
222 // =============================================================================================
223 Standard_Integer TypeToIndex(const TopAbs_ShapeEnum& theType) {
224 return (Standard_Integer) theType;
227 // =============================================================================================
228 // function: GetBoxEnlargedBySubShape
229 // =============================================================================================
230 Bnd_Box GetBoxEnlargedBySubShape(const Standard_Integer theIndex,
231 const BooleanOperations_PShapesDataStructure& PDS) {
232 Bnd_Box aBox = PDS->GetBoundingBox(theIndex);
234 for(Standard_Integer i=1; i<= PDS->NumberOfSuccessors(theIndex); i++) {
235 Standard_Integer asuccessorindex = PDS->GetSuccessor(theIndex, i);
236 aBox.Add(GetBoxEnlargedBySubShape(asuccessorindex, PDS));