// File: ShapeFix_FaceConnect.cxx // Created: Fri Jun 18 11:27:03 1999 // Author: Sergei ZERTCHANINOV // // Copyright: Matra Datavision 1999 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DEB #include #endif //======================================================================= //function : ShapeFix_FaceConnect //======================================================================= ShapeFix_FaceConnect::ShapeFix_FaceConnect() {} //======================================================================= //function : Connect //purpose : //======================================================================= Standard_Boolean ShapeFix_FaceConnect::Add(const TopoDS_Face& aFirst, const TopoDS_Face& aSecond) { if (!aFirst.IsNull() && !aSecond.IsNull()) { // Process first face if (myConnected.IsBound(aFirst)) { // Find list for the first face TopTools_ListOfShape& theFirstList = myConnected(aFirst); // Append second face to the first list TopTools_ListIteratorOfListOfShape theIter; for ( theIter.Initialize(theFirstList); theIter.More(); theIter.Next() ) if (theIter.Value().IsSame(aSecond)) return Standard_True; theFirstList.Append(aSecond); } else { // Append second face to the first list TopTools_ListOfShape theNewFirstList; theNewFirstList.Append(aSecond); myConnected.Bind(aFirst,theNewFirstList); } // Process second face if not same if (!aFirst.IsSame(aSecond)) { if (myConnected.IsBound(aSecond)) { // No need to iterate on faces - append first myConnected(aSecond).Append(aFirst); } else { // Append first face to the second list TopTools_ListOfShape theNewSecondList; theNewSecondList.Append(aFirst); myConnected.Bind(aSecond,theNewSecondList); } } return Standard_True; } return Standard_False; } //======================================================================= //function : Build //purpose : //======================================================================= TopoDS_Shell ShapeFix_FaceConnect::Build (const TopoDS_Shell& shell, const Standard_Real sewtoler, const Standard_Real fixtoler) { TopoDS_Shell result = shell; /*************************************************************** / INITIAL PREPARATIONS / Fill map of original free edges, / fill maps of resulting free and shared edges ***************************************************************/ // Clear maps of free and shared edges myOriFreeEdges.Clear(); myResFreeEdges.Clear(); myResSharEdges.Clear(); TopTools_DataMapOfShapeShape theFreeEdges; TopoDS_Shape theEdge, theFace; // Fill map of free edges / faces for ( TopoDS_Iterator itf(result); itf.More(); itf.Next() ) { theFace = itf.Value(); for ( TopExp_Explorer expe(theFace,TopAbs_EDGE); expe.More(); expe.Next() ) { theEdge = expe.Current(); if (theFreeEdges.IsBound(theEdge)) theFreeEdges.UnBind(theEdge); else theFreeEdges.Bind(theEdge,theFace); } } // Fill maps of original and resulting edges for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theFEIter( theFreeEdges ); theFEIter.More(); theFEIter.Next() ) { // Get pair (face / free edge) theEdge = theFEIter.Key(), theFace = theFEIter.Value(); // Process faces with bad connectivities only if (myConnected.IsBound(theFace) && !BRep_Tool::Degenerated(TopoDS::Edge(theEdge))) { // Add to the map of original free edges if (myOriFreeEdges.IsBound(theFace)) { // Append free edge to the existing list myOriFreeEdges(theFace).Append(theEdge); } else { // Append free edge to the new list TopTools_ListOfShape theNewList; theNewList.Append(theEdge); myOriFreeEdges.Bind(theFace,theNewList); } // Add to the maps of intermediate free and resulting edges if (!myResFreeEdges.IsBound(theEdge)) { TopTools_ListOfShape theFree, theShared; theFree.Append(theEdge); myResFreeEdges.Bind(theEdge,theFree); myResSharEdges.Bind(theEdge,theShared); } } } // Clear the temporary map of free edges theFreeEdges.Clear(); #ifdef DEB //------------------------------- //szv debug - preparation results //------------------------------- if (!myOriFreeEdges.IsEmpty()) { cout<Replace(theREIter.Key()/*.Oriented(TopAbs_FORWARD)*/, theREIter.Value()/*.Oriented(TopAbs_FORWARD)*/); } //smh#8 TopoDS_Shape tmpReShape = theReShape->Apply(result); result = TopoDS::Shell(tmpReShape); if (theReShape->Status(ShapeExtend_OK)) { #ifdef DEB cout<<"Warning: ShapeFix_FaceConnect::Build: Edges not replaced by ReShape"<Status(ShapeExtend_FAIL1)) { #ifdef DEB cout<<"Error: ShapeFix_FaceConnect::Build: ReShape failed on edges"<NbEdges(); i++) { //smh#8 TopoDS_Shape tmpFace = EmpFace.Oriented(TopAbs_FORWARD); if (!SAE.PCurve(sewd->Edge(i), TopoDS::Face(tmpFace), c2d,f,l)) continue; SAWO.Add(c2d->Value(f).XY(),c2d->Value(l).XY()); } SAWO.Perform(); SFW->Load(sewd); SFW->FixReorder(SAWO); SFW->FixReorder(); SFW->SetFace(EmpFace); SFW->SetPrecision(fixtoler); SFW->SetMaxTolerance(sewtoler); SFW->FixEdgeCurves(); SFW->FixSelfIntersection(); theWire = SFW->Wire(); theBuilder.Add(EmpFace,theWire); } // #ifdef AIX CKY : applies to all platforms SFF->Init(EmpFace); // SFF->Init(TopoDS::Face(EmpFace)); TopTools_DataMapOfShapeListOfShape MapWires; MapWires.Clear(); if (SFF->FixOrientation(MapWires)) EmpFace = SFF->Face(); theBuilder.Add(theShell,EmpFace); } result = theShell; if (!theRepVertices.IsEmpty()) { // Prepare vertices to replace TopoDS_Shape theOld, theNew, theRep, theAux; for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theRV1Iter( theRepVertices ); theRV1Iter.More(); theRV1Iter.Next() ) { // Get the old vertex, create empty list of replaced vertices theOld = theRV1Iter.Key(); TopTools_ListOfShape theNewList; // Explore the list of new vertices TopTools_ListIteratorOfListOfShape theN1Iter; for ( theN1Iter.Initialize(theRV1Iter.Value()); theN1Iter.More(); theN1Iter.Next() ) { theNew = theN1Iter.Value(); if (theOldVertices.IsBound(theNew)) { // Vertex has a replacing vertex in the map theRep = theOldVertices(theNew); if (!theRep.IsSame(theOld)) { // Vertex is not in current list theOldVertices.Bind(theRep,theOld); theNewList.Append(theRep); TopTools_ListIteratorOfListOfShape theN3Iter; for ( theN3Iter.Initialize(theNewVertices(theRep)); theN3Iter.More(); theN3Iter.Next() ) { theAux = theN3Iter.Value(); theOldVertices(theAux) = theOld; theNewList.Append(theAux); } theNewVertices.UnBind(theRep); } } else { theOldVertices.Bind(theNew,theOld); theNewList.Append(theNew); } } theNewVertices.Bind(theOld,theNewList); } // Update vertices positions and tolerances TopoDS_Vertex theNewVert, theOldVert; for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theRV2Iter( theNewVertices ); theRV2Iter.More(); theRV2Iter.Next() ) { theNewVert = TopoDS::Vertex(theRV2Iter.Key()); // Calculate the vertex position gp_Pnt theLBound, theRBound, thePosition; theLBound = theRBound = BRep_Tool::Pnt(theNewVert); TopTools_ListIteratorOfListOfShape theN2Iter; for ( theN2Iter.Initialize(theRV2Iter.Value()); theN2Iter.More(); theN2Iter.Next() ) { thePosition = BRep_Tool::Pnt(TopoDS::Vertex(theN2Iter.Value())); Standard_Real val = thePosition.X(); if ( val < theLBound.X() ) theLBound.SetX( val ); else if ( val > theRBound.X() ) theRBound.SetX( val ); val = thePosition.Y(); if ( val < theLBound.Y() ) theLBound.SetY( val ); else if ( val > theRBound.Y() ) theRBound.SetY( val ); val = thePosition.Z(); if ( val < theLBound.Z() ) theLBound.SetZ( val ); else if ( val > theRBound.Z() ) theRBound.SetZ( val ); } thePosition = gp_Pnt((theLBound.XYZ() + theRBound.XYZ())/2.); Standard_Real theTolerance = 0., curtoler; // Calculate the vertex tolerance for ( theN2Iter.Initialize(theRV2Iter.Value()); theN2Iter.More(); theN2Iter.Next() ) { theOldVert = TopoDS::Vertex(theN2Iter.Value()); curtoler = thePosition.Distance(BRep_Tool::Pnt(theOldVert)) + BRep_Tool::Tolerance(theOldVert); if (curtoler > theTolerance) theTolerance = curtoler; } curtoler = thePosition.Distance(BRep_Tool::Pnt(theNewVert)) + BRep_Tool::Tolerance(theNewVert); if (curtoler > theTolerance) theTolerance = curtoler; theBuilder.UpdateVertex( theNewVert, thePosition, theTolerance ); } // Replace vertices theReShape->Clear(); for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theNVIter( theOldVertices ); theNVIter.More(); theNVIter.Next() ) theReShape->Replace(theNVIter.Key().Oriented(TopAbs_FORWARD), theNVIter.Value().Oriented(TopAbs_FORWARD)); //smh#8 TopoDS_Shape tmpshape = theReShape->Apply(result); result = TopoDS::Shell(tmpshape); if (theReShape->Status(ShapeExtend_FAIL1)) { #ifdef DEB cout<<"Error: ShapeFix_FaceConnect::Build: ReShape failed on vertices"<