3 #include "GEOMImpl_GlueDriver.hxx"
4 #include "GEOMImpl_IGlue.hxx"
5 #include "GEOMImpl_Types.hxx"
6 #include "GEOM_Function.hxx"
8 #include <BRep_Tool.hxx>
9 #include <BRep_Builder.hxx>
10 #include <BRepLib.hxx>
11 #include <BRepTools_Quilt.hxx>
12 #include <BRepClass3d_SolidClassifier.hxx>
15 #include <TopExp_Explorer.hxx>
18 #include <TopoDS_Shape.hxx>
19 #include <TopoDS_Face.hxx>
20 #include <TopoDS_Edge.hxx>
21 #include <TopoDS_Vertex.hxx>
22 #include <TopoDS_Compound.hxx>
23 #include <TopoDS_Shell.hxx>
24 #include <TopoDS_Solid.hxx>
25 #include <TopTools_ListOfShape.hxx>
26 #include <TopTools_ListIteratorOfListOfShape.hxx>
29 #include <Precision.hxx>
30 #include <Standard_NullObject.hxx>
31 #include <Standard_ConstructionError.hxx>
33 //=======================================================================
36 //=======================================================================
37 const Standard_GUID& GEOMImpl_GlueDriver::GetID()
39 static Standard_GUID aGlueDriver("FF1BBB63-5D14-4df2-980B-3A668264EA16");
44 //=======================================================================
45 //function : GEOMImpl_GlueDriver
47 //=======================================================================
48 GEOMImpl_GlueDriver::GEOMImpl_GlueDriver()
52 //=======================================================================
53 //function : FindSameFace
54 //purpose : for GLUE_FACES
55 //=======================================================================
56 static TopoDS_Face FindSameFace (const TopoDS_Shape& aShape,
62 for (TopExp_Explorer exf (aShape, TopAbs_FACE); exf.More(); exf.Next()) {
65 aFace = TopoDS::Face(exf.Current());
66 TopTools_ListOfShape liste1;
67 TopTools_ListOfShape liste2;
68 for (TopExp_Explorer exp (aFace, TopAbs_VERTEX); exp.More(); exp.Next()) {
69 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
72 for (TopExp_Explorer exp (F, TopAbs_VERTEX); exp.More(); exp.Next()) {
73 const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
77 if (liste1.Extent() == liste2.Extent())
79 TopTools_ListIteratorOfListOfShape it1 (liste1);
81 for (; it1.More(); it1.Next())
83 bool foundSamePoint = false;
84 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1.Value()));
85 TopTools_ListIteratorOfListOfShape it2 (liste2);
86 for (; it2.More(); it2.Next()) {
87 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2.Value()));
88 double d = P1.Distance(P2);
91 // found Same Point : P1
92 foundSamePoint = true;
96 isSame = isSame && foundSamePoint;
97 if (! isSame) break; // a vertex does not correspond : not same face
102 break; // a face corresponding to F is found
105 if (!isSame) aFace.Nullify(); // return null face
109 //=======================================================================
110 //function : FindSameEdge
111 //purpose : for GLUE_FACES
112 //=======================================================================
113 static TopoDS_Edge FindSameEdge (const TopoDS_Face& nf, TopoDS_Edge& Eold,
116 TopoDS_Face newFace = TopoDS::Face(nf.Oriented(TopAbs_REVERSED));
117 TopoDS_Vertex VFirst, VLast;
118 TopExp::Vertices(Eold, VFirst, VLast);
119 gp_Pnt Pf = BRep_Tool::Pnt(VFirst);
120 gp_Pnt Pl = BRep_Tool::Pnt(VLast);
122 for (TopExp_Explorer ee (newFace, TopAbs_EDGE); ee.More(); ee.Next()) {
123 const TopoDS_Edge& E = TopoDS::Edge(ee.Current());
124 TopoDS_Vertex VFn, VLn;
125 TopExp::Vertices(E, VFn, VLn);
126 gp_Pnt Pfn = BRep_Tool::Pnt(VFn);
127 gp_Pnt Pln = BRep_Tool::Pnt(VLn);
128 double dff = Pf.Distance(Pfn);
129 double dfl = Pf.Distance(Pln);
130 double dlf = Pl.Distance(Pfn);
131 double dll = Pl.Distance(Pln);
132 if ((dff < tol3d) && (dll <tol3d)) {
133 // edge forward : Pf - Pl
134 Enew = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
135 Eold = TopoDS::Edge(Eold.Oriented(TopAbs_FORWARD));
138 if ((dfl < tol3d) && (dlf <tol3d)) {
139 // edge reversed : Pf - Pl
140 Enew = TopoDS::Edge(E.Oriented(TopAbs_REVERSED));
141 Eold = TopoDS::Edge(Eold.Oriented(TopAbs_FORWARD));
148 //=======================================================================
149 //function : GlueFaces
151 //=======================================================================
152 TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape,
153 const Standard_Real theTolerance)
155 // prendre un premier shell dans la liste des shells
156 // initialiser un compshell avec ce shell
157 // tant qu'il reste des shells dans la liste
158 // chercher un shell qui a des faces en commun avec le compshell
159 // creer un BRepTools_Quilt
160 // recenser les faces communes issues du compshell, les ajouter au quilt
161 // recenser les faces restantes du shell a inclure, les ajouter au quilt
162 // recenser les edges en double, a remplacer
163 // pour chaque paire d'edge
164 // tester l'orientation relative des aretes
165 // bind dans le quilt de Eold.Forward et Enew.Forward (ou reverse)
166 // recuperer le nouveau shell
167 // l'incorporer dans le compshell
168 // appliquer BRepTools_SameParameter au compshell
169 // (rendre parametres 2D des edges identiques aux parametres 3D)
175 bu.MakeCompound(C); // empty compound;
176 TopTools_ListOfShape shellList;
177 for (TopExp_Explorer exp (theShape, TopAbs_SHELL); exp.More(); exp.Next()) {
178 const TopoDS_Shell& S = TopoDS::Shell(exp.Current());
181 TopTools_ListIteratorOfListOfShape its (shellList);
183 Standard_ConstructionError::Raise("Glue aborted : no shell in shape");
185 TopoDS_Shell S = TopoDS::Shell(its.Value());
186 bu.Add(C, S); // add first shell to compound
187 shellList.Remove(its);
188 bool shellAdded = true;
189 while ((shellList.Extent() > 0) && shellAdded) {
191 its.Initialize(shellList);
192 for (; its.More(); its.Next()) {
193 TopTools_ListOfShape newFaces; // common faces from new compound
194 TopTools_ListOfShape oldFaces; // common faces from shell to add
195 TopTools_ListOfShape addFaces; // not common faces from shell to add
196 TopTools_ListOfShape newEdges; // common edges from new compound
197 TopTools_ListOfShape oldEdges; // common edges from face to add
200 bu.MakeCompound(CFN); // empty compound for new faces
201 bu.MakeCompound(CFO); // empty compound for old faces
202 S = TopoDS::Shell(its.Value());
203 for (TopExp_Explorer exp (S, TopAbs_FACE); exp.More(); exp.Next()) {
204 // try to find corresponding face in new compound
205 TopoDS_Face F = TopoDS::Face(exp.Current());
206 TopoDS_Face newFace = FindSameFace(C,F,theTolerance);
207 if (! newFace.IsNull())
210 newFaces.Append(newFace);
211 bu.Add(CFN, newFace); // common faces from new compound
213 for (TopExp_Explorer ee (F, TopAbs_EDGE); ee.More(); ee.Next()) {
215 TopoDS_Edge Eold = TopoDS::Edge(ee.Current());
216 TopoDS_Edge Enew = FindSameEdge(newFace, Eold, theTolerance);
218 Standard_ConstructionError::Raise("Glue aborted : no same edge in same face");
220 oldEdges.Append(Eold);
221 newEdges.Append(Enew);
225 bu.Add(CFO, F); // not common faces from shell to add
228 if (!newFaces.IsEmpty()) {
231 BRepTools_Quilt glue;
233 TopTools_ListIteratorOfListOfShape ito (oldEdges);
234 TopTools_ListIteratorOfListOfShape itn (newEdges);
235 for (; ito.More(); ito.Next()) {
237 glue.Bind(TopoDS::Edge(ito.Value()), TopoDS::Edge(itn.Value()));
241 TopoDS_Compound newc = TopoDS::Compound(glue.Shells());
242 for (TopExp_Explorer exs (newc, TopAbs_SHELL); exs.More(); exs.Next()) {
243 TopoDS_Shell NS = TopoDS::Shell(exs.Current());
246 shellList.Remove(its);
247 // remove shell from list
253 TopExp_Explorer exp (C, TopAbs_SHELL);
254 Standard_Integer ish = 0;
260 for (; exp.More(); exp.Next()) {
261 TopoDS_Shape Sh = exp.Current();
264 BRepClass3d_SolidClassifier SC(Sol);
265 SC.PerformInfinitePoint(1.E-6); // cf. BRepFill_Confusion() - BRepFill_Evolved.cxx
266 if (SC.State() == TopAbs_IN) {
268 B.Add(Sol,Sh.Reversed());
279 BRepLib::SameParameter(aShape, 1.E-5, Standard_True);
283 //=======================================================================
286 //=======================================================================
287 Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
289 if (Label().IsNull()) return 0;
290 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
292 GEOMImpl_IGlue aCI (aFunction);
293 Standard_Integer aType = aFunction->GetType();
297 if (aType == GLUE_FACES) {
298 Handle(GEOM_Function) aRefBase = aCI.GetBase();
299 TopoDS_Shape aShapeBase = aRefBase->GetValue();
300 if (aShapeBase.IsNull()) {
301 Standard_NullObject::Raise("Shape for gluing is null");
304 Standard_Real tol3d = aCI.GetTolerance();
305 aShape = GlueFaces(aShapeBase, tol3d);
310 if (aShape.IsNull()) return 0;
312 aFunction->SetValue(aShape);
314 log.SetTouched(Label());
320 //=======================================================================
321 //function : GEOMImpl_GlueDriver_Type_
323 //=======================================================================
324 Standard_EXPORT Handle_Standard_Type& GEOMImpl_GlueDriver_Type_()
327 static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
328 if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
329 static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
330 if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
331 static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
332 if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
335 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
336 static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_GlueDriver",
337 sizeof(GEOMImpl_GlueDriver),
339 (Standard_Address)_Ancestors,
340 (Standard_Address)NULL);
345 //=======================================================================
346 //function : DownCast
348 //=======================================================================
349 const Handle(GEOMImpl_GlueDriver) Handle(GEOMImpl_GlueDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
351 Handle(GEOMImpl_GlueDriver) _anOtherObject;
353 if (!AnObject.IsNull()) {
354 if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_GlueDriver))) {
355 _anOtherObject = Handle(GEOMImpl_GlueDriver)((Handle(GEOMImpl_GlueDriver)&)AnObject);
359 return _anOtherObject ;