+
+//=======================================================================
+//function : IsInside
+//purpose : Return True if the first vertex of S1 inside S2.
+// If S1.IsNull(), check infinite point against S2.
+//=======================================================================
+
+Standard_Boolean Partition_Spliter::IsInside (const TopoDS_Shape& theS1,
+ const TopoDS_Shape& theS2)
+{
+ BRepClass3d_SolidClassifier aClassifier( theS2 );
+
+ TopExp_Explorer expl( theS1, TopAbs_VERTEX );
+ if (!expl.More())
+ aClassifier.PerformInfinitePoint( ::RealSmall());
+ else
+ {
+ const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() );
+ aClassifier.Perform (BRep_Tool::Pnt( aVertex ),
+ BRep_Tool::Tolerance( aVertex ));
+ }
+
+ return ( aClassifier.State() == TopAbs_IN );
+}
+
+//=======================================================================
+//function : GetOriginalShape
+//purpose : Return the shape aShape originates from. aShape
+// should be a face or more complex result shape
+//=======================================================================
+
+TopoDS_Shape Partition_Spliter::GetOriginalShape(const TopoDS_Shape& theShape) const
+{
+ TopoDS_Shape anOrigShape;
+
+ TopExp_Explorer expl( theShape, TopAbs_FACE);
+ if (expl.More())
+ {
+
+ TopoDS_Shape aFace = expl.Current();
+ if (myImagesFaces.IsImage( aFace ))
+ aFace = myImagesFaces.Root( aFace );
+ anOrigShape = myFaceShapeMap.Find( aFace );
+ }
+ return anOrigShape;
+}
+
+//=======================================================================
+//function : FindToolsToReconstruct
+//purpose : find and store as objects tools which interfere
+// with solids or are inside solids without
+// an interference
+//=======================================================================
+
+void Partition_Spliter::FindToolsToReconstruct()
+{
+ if (myMapTools.IsEmpty())
+ return;
+
+ Standard_Integer nbFoundTools = 0;
+
+ // build edge - face map in order to detect interference with section edges
+ TopTools_IndexedDataMapOfShapeListOfShape EFM;
+ TopTools_MapIteratorOfMapOfShape aMapIt;
+ for (aMapIt.Initialize(myMapTools); aMapIt.More(); aMapIt.Next())
+ TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM);
+ for (aMapIt.Initialize(myMapFaces); aMapIt.More(); aMapIt.Next())
+ TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM);
+
+ TopTools_MapOfShape aCurrentSolids, aCheckedShapes;
+
+ // faces cut by new edges
+ TopTools_MapOfShape & aSectionFaces = myInter3d.TouchedFaces();
+
+ // keep solids interfering with each other in aCurrentSolids map
+ // and add tool faces intersecting solids as object shapes
+
+ TopTools_ListIteratorOfListOfShape itS, itF, itCF, itE;
+ for (itS.Initialize( myListShapes ); itS.More(); itS.Next()) {
+ TopExp_Explorer expSo (itS.Value(), TopAbs_SOLID);
+ for (; expSo.More(); expSo.Next()) {
+
+ // check if a solid has been already processed
+ const TopoDS_Shape & aSo = expSo.Current();
+ if (!aCheckedShapes.Add( aSo ))
+ continue;
+ aCurrentSolids.Add( aSo );
+
+ // faces to check
+ TopTools_ListOfShape aFacesToCheck;
+ TopExp_Explorer exp( aSo, TopAbs_FACE );
+ for ( ; exp.More(); exp.Next())
+ aFacesToCheck.Append ( exp.Current());
+
+ // add other shapes interefering with a solid.
+ // iterate faces to check while appending new ones
+ for (itCF.Initialize (aFacesToCheck) ; itCF.More(); itCF.Next())
+ {
+ const TopoDS_Shape& aCheckFace = itCF.Value();
+// if (!aCheckedShapes.Add( aCheckFace ))
+// continue;
+
+ // find faces interfering with aCheckFace
+ TopTools_ListOfShape anIntFaces;
+
+ // ** 1. faces intersecting aCheckFace with creation of new edges on it
+ if ( myAsDes->HasDescendant( aCheckFace ))
+ {
+ // new edges on aCheckFace
+ const TopTools_ListOfShape& NEL = myAsDes->Descendant( aCheckFace );
+ for (itE.Initialize( NEL); itE.More(); itE.Next())
+ {
+ const TopoDS_Shape & aNewEdge = itE.Value();
+ if (!aCheckedShapes.Add( aNewEdge ))
+ continue;
+
+ // faces interfering by aNewEdge
+ itF.Initialize (myAsDes->Ascendant( aNewEdge ));
+ for (; itF.More(); itF.Next())
+ if (aCheckFace != itF.Value())
+ anIntFaces.Append( itF.Value() );
+
+ // ** 2. faces having section edge aNewEdge on aFacesToCheck
+ if (EFM.Contains( aNewEdge))
+ {
+ itF.Initialize ( EFM.FindFromKey (itE.Value()));
+ for (; itF.More(); itF.Next())
+ if (aCheckFace != itF.Value())
+ anIntFaces.Append( itF.Value() );
+ }
+ }
+ }
+
+ // ** 3. faces cut by edges of aCheckFace
+ TopExp_Explorer expE (aCheckFace, TopAbs_EDGE);
+ for ( ; expE.More(); expE.Next())
+ {
+ const TopoDS_Shape & aCheckEdge = expE.Current();
+ if (aCheckedShapes.Add( aCheckEdge ) &&
+ myInter3d.IsSectionEdge( TopoDS::Edge( aCheckEdge )))
+ {
+ itF.Initialize( myInter3d.SectionEdgeFaces( TopoDS::Edge( aCheckEdge )));
+ for (; itF.More(); itF.Next())
+ if (aCheckFace != itF.Value())
+ anIntFaces.Append( itF.Value() );
+ }
+ }
+
+ // process faces interfering with aCheckFace and shapes they
+ // belong to
+ for (itF.Initialize (anIntFaces); itF.More(); itF.Next())
+ {
+ const TopoDS_Shape & F = itF.Value();
+ if (! aCheckedShapes.Add( F ))
+ continue;
+
+ Standard_Boolean isTool = myMapTools.Contains( F );
+ if (isTool &&
+ myFaceShapeMap( aCheckFace ).ShapeType() == TopAbs_SOLID )
+ {
+ // a tool interfering with a solid
+ if (aSectionFaces.Contains( F ))
+ AddShape( F );
+ ++ nbFoundTools;
+ if (nbFoundTools == myMapTools.Extent())
+ return;
+ }
+
+ const TopoDS_Shape & S = myFaceShapeMap( F );
+ if (aCheckedShapes.Add( S ))
+ {
+ // a new shape interefering with aCurrentSolids is found
+ if (!isTool && S.ShapeType() == TopAbs_SOLID)
+ aCurrentSolids.Add ( S );
+ // add faces to aFacesToCheck list
+ for ( exp.Init( S, TopAbs_FACE ); exp.More(); exp.Next())
+ aFacesToCheck.Append ( exp.Current() );
+ }
+ }
+ } // loop on aFacesToCheck
+
+ // Here aCurrentSolids contains all solids interfering with each other.
+ // aCheckedShapes contains all faces belonging to shapes included
+ // in or interfering with aCurrentSolids or previously checked solids.
+ // Test if tool faces that do not interefere with other shapes are
+ // wrapped by any of aCurrentSolids
+
+ TopTools_MapIteratorOfMapOfShape aSolidIt (aCurrentSolids);
+ for ( ; aSolidIt.More(); aSolidIt.Next())
+ {
+ const TopoDS_Shape & aSolid = aSolidIt.Key();
+ TopTools_MapOfShape aCheckedTools( myMapTools.Extent() );
+
+ TopTools_MapIteratorOfMapOfShape aToolIt (myMapTools);
+ for ( ; aToolIt.More(); aToolIt.Next())
+ {
+ const TopoDS_Shape & aToolFace = aToolIt.Key();
+ if (aCheckedShapes.Contains( aToolFace ) || // already found
+ aCheckedTools.Contains( aToolFace )) // checked against aSolid
+ continue;
+
+ const TopoDS_Shape & aToolShape = myFaceShapeMap( aToolFace );
+ TopExp_Explorer aToolFaceIt( aToolShape, TopAbs_FACE );
+
+ Standard_Boolean isInside = IsInside( aToolShape, aSolid );
+ for ( ; aToolFaceIt.More(); aToolFaceIt.Next() )
+ {
+ const TopoDS_Shape & aTool = aToolFaceIt.Current();
+ aCheckedTools.Add( aTool );
+ if (isInside)
+ {
+ if (aSectionFaces.Contains( aTool ))
+ AddShape( aTool );
+ ++ nbFoundTools;
+ if (nbFoundTools == myMapTools.Extent())
+ return;
+ aCheckedShapes.Add( aTool );
+ }
+ }
+ }
+ }
+
+ } // loop on solid shapes
+ }
+}