1 // File: ShHealOper_Sewing.cxx
2 // Created: 29.04.04 15:07:10
3 // Author: Galina KULIKOVA
4 // < MODULE = KERNEL> <PACKAGE = ShHealOper> : <Shape Healing Operations>
5 // Copyright (C) 2003 CEA
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 2.1 of the License.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <ShHealOper_Sewing.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopoDS_Shell.hxx>
27 #include <BRep_Builder.hxx>
28 #include <ShapeFix_Shell.hxx>
29 #include <TopTools_HSequenceOfShape.hxx>
30 #include <TopoDS_Shell.hxx>
31 #include <BRep_Builder.hxx>
32 #include <ShapeAnalysis_FreeBounds.hxx>
33 #include <TopoDS_Compound.hxx>
35 #include <TopoDS_Iterator.hxx>
36 #include <TopTools_MapOfShape.hxx>
37 //=======================================================================
38 //function : ShHealOper_Sewing()
39 //purpose : Constructor
40 //=======================================================================
43 ShHealOper_Sewing::ShHealOper_Sewing (const TopoDS_Shape& theShape,
44 const Standard_Real theTolerance)
47 myTolerance = theTolerance;
49 //=======================================================================
52 //=======================================================================
54 void ShHealOper_Sewing::Init(const TopoDS_Shape& theShape)
56 ShHealOper_Tool::Init(theShape);
57 myTolerance = Precision::Confusion();
58 myEdgesMode = Standard_False;
59 myFacesMode = Standard_True;
60 myNonManifoldMode = Standard_False;
61 myHistoryLevel = TopAbs_FACE;
63 //=======================================================================
66 //=======================================================================
68 Standard_Boolean ShHealOper_Sewing::Perform()
70 TopTools_SequenceOfShape theSeqShapes;
71 return sewing(theSeqShapes);
73 //=======================================================================
76 //=======================================================================
78 Standard_Boolean ShHealOper_Sewing::Perform(const TopTools_SequenceOfShape& theSeqShapes)
80 return sewing(theSeqShapes);
83 //=======================================================================
86 //=======================================================================
88 Standard_Boolean ShHealOper_Sewing::sewing(const TopTools_SequenceOfShape& theSeqShapes)
90 myDone = Standard_False;
91 myErrorStatus = ShHealOper_NotError;
92 if(myInitShape.IsNull()) {
93 myErrorStatus = ShHealOper_InvalidParameters;
97 Handle(BRepAlgo_Sewing) aSewing = new BRepAlgo_Sewing;
98 aSewing->Load(myInitShape);
99 aSewing->SetTolerance(myTolerance);
100 aSewing->SetFaceMode(myFacesMode);
101 aSewing->SetFloatingEdgesMode(myEdgesMode);
102 aSewing->SetNonManifoldMode(myNonManifoldMode);
103 Standard_Integer j =1;
104 for( ; j <= theSeqShapes.Length();j++)
105 aSewing->Add(theSeqShapes.Value(j));
108 const TopoDS_Shape aSewShape = aSewing->SewedShape();
109 if(aSewShape.IsNull()) {
110 myErrorStatus = ShHealOper_ErrorExecution;
113 if(aSewShape.IsSame(myInitShape))
116 //analysis either sewing was made by changing number of shells
117 myDone = isSewed(aSewShape);
119 //keep modification of the subshapes in the Context.
120 TopExp_Explorer aExp(myInitShape,TopAbs_FACE);
121 for( ; aExp.More(); aExp.Next())
122 myDone = (getModifications( aExp.Current(),aSewing) || myDone);
124 TopoDS_Shape aTempShape = myContext->Apply(aSewShape);
125 //obtained shells with fixed orientation for manifold and nonmanifold shells
127 myDone = getShells(aTempShape) || myDone;
129 //obtained manifold wires if sewing edges was performed.
131 myDone = getWires(aTempShape) || myDone;
134 myResultShape = myContext->Apply(aTempShape);
138 //=======================================================================
139 //function : getShells
141 //=======================================================================
143 Standard_Boolean ShHealOper_Sewing::getShells(const TopoDS_Shape& theSewShape) const
145 Standard_Boolean isDone = Standard_False;
146 TopoDS_Shape aTmpShape = theSewShape;
147 if(myNonManifoldMode) {
148 TopoDS_Shell tempShell;
150 aB.MakeShell(tempShell);
152 for(TopExp_Explorer aExpf(theSewShape,TopAbs_FACE);aExpf.More(); aExpf.Next())
153 aB.Add(tempShell,aExpf.Current());
154 aTmpShape = tempShell;
155 myContext->Replace(theSewShape,aTmpShape);
158 Handle(ShapeFix_Shell) asfs = new ShapeFix_Shell;
159 asfs->SetContext(myContext);
160 TopExp_Explorer aexpShell(aTmpShape,TopAbs_SHELL);
161 for ( ; aexpShell.More(); aexpShell.Next())
162 isDone = (asfs->FixFaceOrientation(TopoDS::Shell(aexpShell.Current()),
163 Standard_True,myNonManifoldMode) || isDone);
167 //=======================================================================
168 //function : getWires
170 //=======================================================================
172 Standard_Boolean ShHealOper_Sewing::getWires(const TopoDS_Shape& theSewShape) const
174 if(theSewShape.ShapeType() != TopAbs_COMPOUND)
175 return Standard_False;
177 Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
178 TopExp_Explorer aexpEdges(theSewShape,TopAbs_EDGE,TopAbs_WIRE);
179 for ( ; aexpEdges.More(); aexpEdges.Next()) {
180 aSeqEdges->Append(aexpEdges.Current());
182 if(aSeqEdges->Length() <2)
183 return Standard_False;
184 //get manifold wires from sewed edges.
185 Standard_Real aTol = 0.;
186 Standard_Boolean aShared = Standard_True;
187 Handle(TopTools_HSequenceOfShape) aTmpWires = new TopTools_HSequenceOfShape;
188 ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges, aTol, aShared, aTmpWires);
190 TopTools_MapOfShape aMapEdges;
191 Standard_Integer i =1;
192 for( ; i <= aSeqEdges->Length(); i++)
193 aMapEdges.Add(aSeqEdges->Value(i));
195 //remove free edges from result shape.
196 TopoDS_Compound aNewComp;
197 deleteFreeEdges(theSewShape,aMapEdges,aNewComp);
199 //add new wires in the result shape.
201 for( i =1; i <= aTmpWires->Length(); i++) {
202 TopoDS_Iterator aite(aTmpWires->Value(i));
203 Standard_Integer nbe =0;
205 for( ; aite.More() && nbe < 3; aite.Next(),nbe++)
212 aB.Add(aNewComp,aTmpWires->Value(i));
215 myContext->Replace(theSewShape,aNewComp);
216 return Standard_True;
218 //=======================================================================
219 //function : getHistory
221 //=======================================================================
223 Standard_Boolean ShHealOper_Sewing::getModifications(const TopoDS_Shape& theShape,
224 const Handle(BRepAlgo_Sewing)& theSewing) const
226 if((Standard_Integer)theShape.ShapeType() > (Standard_Integer)myHistoryLevel)
227 return Standard_False;
229 Standard_Boolean isDone = theSewing->IsModifiedSubShape(theShape);
231 TopoDS_Shape aNewShape = theSewing->ModifiedSubShape(theShape);
232 myContext->Replace(theShape,aNewShape);
234 TopoDS_Iterator aIt(theShape);
235 for( ; aIt.More(); aIt.Next()) {
236 isDone = (getModifications( aIt.Value(),theSewing) || isDone);
241 //=======================================================================
244 //=======================================================================
246 Standard_Boolean ShHealOper_Sewing::isSewed(const TopoDS_Shape& theShape) const
248 Standard_Integer nbNewShells =0;
249 Standard_Integer nbOldShells =0;
250 TopExp_Explorer aExpShells(theShape,TopAbs_SHELL);
251 for( ; aExpShells.More(); aExpShells.Next())
253 for( aExpShells.Init(myInitShape,TopAbs_SHELL); aExpShells.More(); aExpShells.Next())
255 return (nbNewShells != nbOldShells);
257 //=======================================================================
258 //function : deleteFreeEdges
260 //=======================================================================
262 void ShHealOper_Sewing::deleteFreeEdges(const TopoDS_Shape& theSewShape,
263 TopTools_MapOfShape& theMapEdges,
264 TopoDS_Compound& theNewComp) const
268 aB.MakeCompound(theNewComp);
269 TopoDS_Iterator aIt(theSewShape);
271 for( ; aIt.More(); aIt.Next()) {
272 if((aIt.Value().ShapeType() == TopAbs_EDGE ) && theMapEdges.Contains(aIt.Value()))
274 else if(aIt.Value().ShapeType() == TopAbs_COMPOUND) {
276 deleteFreeEdges(aIt.Value(),theMapEdges,aC);
277 aB.Add(theNewComp,aC);
280 aB.Add(theNewComp,aIt.Value());