1 // Created on: 1998-08-19
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #include <TopOpeBRepDS_GapFiller.ixx>
24 #include <TopExp_Explorer.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <TopAbs_ShapeEnum.hxx>
28 #include <TopTools_ListIteratorOfListOfShape.hxx>
29 #include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
30 #include <Precision.hxx>
31 #include <TopOpeBRepDS_connex.hxx>
32 #include <TopOpeBRepDS_Point.hxx>
33 #include <TColgp_SequenceOfPnt.hxx>
34 #include <TColStd_MapOfTransient.hxx>
36 #include <BRepAdaptor_Curve.hxx>
37 #include <BRepAdaptor_Surface.hxx>
45 #include <Geom2d_Curve.hxx>
48 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettraceGAP();
49 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GetcontextNOGAP();
52 //=======================================================================
53 //function : TopOpeBRepDS_GapFiller
55 //=======================================================================
57 TopOpeBRepDS_GapFiller::TopOpeBRepDS_GapFiller(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
60 myGapTool = new TopOpeBRepDS_GapTool(HDS);
61 myAsso = new TopOpeBRepDS_Association();
65 //=======================================================================
68 //=======================================================================
70 void TopOpeBRepDS_GapFiller::Perform()
74 if (TopOpeBRepDS_GetcontextNOGAP () != 0) return;
77 myGapTool->Init(myHDS);
78 TColStd_MapOfInteger View;
79 //------------------------------------------------------------
81 //------------------------------------------------------------
82 Standard_Integer NbCurves = myHDS->NbCurves();
83 for (Standard_Integer i = 1; i <= NbCurves; i++) {
84 TopOpeBRepDS_ListOfInterference& LI = myHDS->ChangeDS().ChangeCurveInterferences(i);
85 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) {
86 TopOpeBRepDS_ListOfInterference ALI;
87 const Handle(TopOpeBRepDS_Interference)& I = it.Value();
88 if (I->GeometryType() == TopOpeBRepDS_POINT) {
89 if (View.Add(I->Geometry())) {
90 FindAssociatedPoints (I,ALI);
91 myAsso->Associate(I,ALI);
96 //--------------------------------------------------------
97 // Modification des Geometries
98 //--------------------------------------------------------
102 //=======================================================================
103 //function : Contains
105 //=======================================================================
107 Standard_Boolean Contains (const TopoDS_Shape& F,const TopoDS_Shape& E)
110 for (exp.Init(F,E.ShapeType()); exp.More(); exp.Next()){
111 // for (TopExp_Explorer exp(F,E.ShapeType()); exp.More(); exp.Next()){
112 if (exp.Current().IsSame(E)) return 1;
118 //=======================================================================
119 //function : FindAssociatedPoints
121 //=======================================================================
123 void TopOpeBRepDS_GapFiller::FindAssociatedPoints(const Handle(TopOpeBRepDS_Interference)& I,
124 TopOpeBRepDS_ListOfInterference& LI)
126 TopOpeBRepDS_ListIteratorOfListOfInterference itSI(myGapTool->SameInterferences(I));
127 for (; itSI.More();itSI.Next()){
128 if (myAsso->HasAssociation(itSI.Value())) return;
132 if (TopOpeBRepDS_GettraceGAP() == 1) {
134 cout<<"-----------------------------------------------------"<<endl;
135 cout<<" Association Point "<<I->Geometry()<<endl;
139 //------------------------------------------------------------------------
140 // PREMIERE PASSE : Recherche de l association parmi les points qui sont:
141 // - sur la meme arete
142 // - sur l autre face connexe a l arete.
143 // - Dans la meme face coupante.
144 //------------------------------------------------------------------------
145 //----------------------------------------------
146 // LI = { ensemble des interference sur l'arete}
147 //----------------------------------------------
149 if (!myGapTool->EdgeSupport(I,E)) {
152 AddPointsOnShape(E,LI);
155 if (!myGapTool->FacesSupport(I,F1,F2)) {
159 if (!Contains(F1,E)) {F = F2; F2 = F1; F1 = F;}
161 const TopTools_ListOfShape& LF = FDSCNX_EdgeConnexitySameShape(E,myHDS);
162 //------------------------------------------------------------------------
163 // Si le point de I est sur deux faces connexes a E => connexite des sections
164 // => pas d association a faire.
165 //------------------------------------------------------------------------
166 // for (TopTools_ListIteratorOfListOfShape itLF(LF); itLF.More(); itLF.Next()) {
167 TopTools_ListIteratorOfListOfShape itLF(LF) ;
168 for ( ; itLF.More(); itLF.Next()) {
169 if (!itLF.Value().IsSame(F1)) {
170 if (IsOnFace(I,TopoDS::Face(itLF.Value()))) {
176 //------------------------------------------------------------------------
177 // LI = { ensemble des interference sur l'arete && sur une autre section ds
178 // la Face connexe par E}
179 //------------------------------------------------------------------------
181 for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
182 if (!itLF.Value().IsSame(F1)) {
183 FilterByFace(TopoDS::Face(itLF.Value()),LI);
186 //--------------------------------------------
187 // LI = LI && point dans la meme face Support2
188 //--------------------------------------------
190 FilterByFace (F2, LI);
192 //-------------------------------
193 // Controle et Selection metrique
194 //-------------------------------
196 FilterByIncidentDistance (F2,I,LI);
203 if (TopOpeBRepDS_GettraceGAP() != 0) {
204 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
205 for (it.Initialize(LI); it.More(); it.Next()) {
206 cout<<" "<<it.Value()->Geometry();
214 //=======================================================================
215 //function : CheckConnexity
217 //=======================================================================
219 //Standard_Boolean TopOpeBRepDS_GapFiller::CheckConnexity(TopOpeBRepDS_ListOfInterference& LI)
220 Standard_Boolean TopOpeBRepDS_GapFiller::CheckConnexity(TopOpeBRepDS_ListOfInterference& )
225 //=======================================================================
226 //function : AddPointsOnFace
228 //=======================================================================
230 void TopOpeBRepDS_GapFiller::AddPointsOnShape (const TopoDS_Shape& S,
231 TopOpeBRepDS_ListOfInterference& LI)
233 const TopOpeBRepDS_ListOfInterference& LIOnE = myHDS->DS().ShapeInterferences(S);
234 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LIOnE); it.More(); it.Next()){
235 LI.Append(it.Value());
239 //=======================================================================
240 //function : AddPointsOnConnexShape
242 //=======================================================================
244 //void TopOpeBRepDS_GapFiller::AddPointsOnConnexShape(const TopoDS_Shape& // F,
245 // const TopOpeBRepDS_ListOfInterference& LI)
246 void TopOpeBRepDS_GapFiller::AddPointsOnConnexShape(const TopoDS_Shape& ,
247 const TopOpeBRepDS_ListOfInterference& )
252 //=======================================================================
253 //function : FilterbyFace
255 //=======================================================================
257 void TopOpeBRepDS_GapFiller::FilterByFace(const TopoDS_Face& F,
258 TopOpeBRepDS_ListOfInterference& LI)
260 //------------------------------------------------------------------------
261 // il ne restera dans LI que les interference dont une des representation
262 // a ete calculee sur F .
263 //------------------------------------------------------------------------
264 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
266 if (!IsOnFace(it.Value(),F)) {
275 //=======================================================================
276 //function : IsOnFace
278 //=======================================================================
280 Standard_Boolean TopOpeBRepDS_GapFiller::IsOnFace
281 (const Handle(TopOpeBRepDS_Interference)& I,
282 const TopoDS_Face& F) const
284 TopOpeBRepDS_Curve C;
285 if (myGapTool->Curve(I,C)) {
288 if (S1.IsSame(F)) return 1;
289 if (S2.IsSame(F)) return 1;
295 //=======================================================================
296 //function : FilterbyEdge
298 //=======================================================================
300 void TopOpeBRepDS_GapFiller::FilterByEdge(const TopoDS_Edge& E,
301 TopOpeBRepDS_ListOfInterference& LI)
303 // il ne restera dans LI que les interference dont une des representation
305 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
307 if (!IsOnEdge(it.Value(),E)) {
316 //=======================================================================
317 //function : IsOnEdge
319 //=======================================================================
321 Standard_Boolean TopOpeBRepDS_GapFiller::IsOnEdge
322 (const Handle(TopOpeBRepDS_Interference)& I,
323 const TopoDS_Edge& E) const
325 const TopOpeBRepDS_ListOfInterference& LI = myGapTool->SameInterferences(I);
326 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) {
327 const Handle(TopOpeBRepDS_Interference)& IC = it.Value();
328 if (IC->SupportType() == TopOpeBRepDS_EDGE) {
329 const TopoDS_Shape& S1 = myHDS->Shape(IC->Support());
330 if (S1.IsSame(E)) return 1;
338 //=======================================================================
341 //=======================================================================
343 static Standard_Boolean Normal(const Handle(TopOpeBRepDS_GapTool)& A,
344 const Handle(TopOpeBRepDS_HDataStructure)& HDS,
345 const Handle(TopOpeBRepDS_Interference)& I,
346 const TopoDS_Face& F,
350 TopOpeBRepDS_Kind GK,SK;
351 Standard_Integer IG,IS;
356 BRepAdaptor_Surface S(F);
357 if (S.GetType() == GeomAbs_Plane) {
358 D = S.Plane().Axis().Direction();
362 const TopOpeBRepDS_ListOfInterference& LI = A->SameInterferences(I);
363 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) {
364 const Handle(TopOpeBRepDS_Interference)& IC = it.Value();
365 IC->GKGSKS(GK,IG,SK,IS);
366 if (SK == TopOpeBRepDS_CURVE) {
367 const TopOpeBRepDS_Curve& C = HDS->Curve(IS);
368 Standard_Real P = (*((Handle(TopOpeBRepDS_CurvePointInterference)*)&IC))->Parameter();
373 if (C.Curve1().IsNull()) return 0;
374 P2d = C.Curve1()->Value(P);
377 if (C.Curve2().IsNull()) return 0;
378 P2d = C.Curve2()->Value(P);
381 if (S.UContinuity() >= GeomAbs_C1 && S.VContinuity() >= GeomAbs_C1) {
382 S.D1(P2d.X(),P2d.Y(),PS,TU,TV);
384 // if (N.SquareMagnitude() >= gp::Resolution()); { // !!
385 if (N.SquareMagnitude() >= gp::Resolution()) {
396 //=======================================================================
397 //function : FilterByIncidentDistance
399 //=======================================================================
401 void TopOpeBRepDS_GapFiller::FilterByIncidentDistance(const TopoDS_Face& F,
402 const Handle(TopOpeBRepDS_Interference)& I,
403 TopOpeBRepDS_ListOfInterference& LI)
405 Standard_Real DistMin = Precision::Infinite();
406 Handle(TopOpeBRepDS_Interference) ISol;
408 const TopOpeBRepDS_Point& PI1 = myHDS->Point(I->Geometry());
409 const gp_Pnt GPI = PI1.Point();
411 BRepAdaptor_Surface S(F,0);
413 Standard_Real TolDef = 0.94;// cos(20degre);
414 Standard_Real TolDist = 20*PI1.Tolerance();
416 Standard_Boolean Ok1 = Normal(myGapTool,myHDS,I,F,N1);
418 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);it.More(); it.Next()) {
420 const Handle(TopOpeBRepDS_Interference)& CI = it.Value();
422 if (CI->HasSameGeometry(I)) continue;
424 Standard_Boolean Ok2 = Normal(myGapTool,myHDS,CI,F,N2);
425 const TopOpeBRepDS_Point& P = myHDS->Point((CI->Geometry()));
426 const gp_Pnt GP = P.Point();
427 Standard_Real Dist = GP.Distance(GPI);
429 //---------------------------------------------------------------------------
431 // Si les points sont plutot ecartes, on regarde si les Normales sur la face
433 //---------------------------------------------------------------------------
434 if (Dist > TolDist) {
436 if (N1.Dot(N2) < TolDef) {
443 if (Dist < DistMin) {
450 if (!ISol.IsNull()) {
453 if (TopOpeBRepDS_GettraceGAP() == 1){
454 cout << " Distance Minimum :"<<DistMin<<endl;
460 //=======================================================================
461 //function : BuildNewPoint
463 //=======================================================================
464 //unreferenced function, commented
467 static void BuildNewPoint (const TColgp_SequenceOfPnt& LP,
468 const Standard_Real& TolMax,
469 TopOpeBRepDS_Point& Point)
471 if (LP.IsEmpty()) return;
472 Standard_Real xp = 0.,yp = 0.,zp = 0.;
474 Standard_Integer i,Nb = LP.Length();
475 for (i = 1; i <= Nb; i++) {
476 const gp_Pnt& CP = LP(i);
477 xp+= CP.X();yp+=CP.Y();zp+=CP.Z();
479 xp/=Nb;yp/=Nb;zp/=Nb;
482 Standard_Real DistMax = 0;
483 for (i = 1; i <= Nb; i++) {
484 const gp_Pnt& CP = LP(i);
485 DistMax = Max(CP.Distance(NP),DistMax);
487 Point.ChangePoint() = NP;
488 Point.Tolerance(DistMax+TolMax);
492 //=======================================================================
493 //function : ReBuildGeom
495 //=======================================================================
497 void TopOpeBRepDS_GapFiller::ReBuildGeom(const Handle(TopOpeBRepDS_Interference)& I,
498 TColStd_MapOfInteger& View)
500 if (!myAsso->HasAssociation(I)) return;
502 TopOpeBRepDS_ListOfInterference& LI = myAsso->Associated(I);
503 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
506 if (TopOpeBRepDS_GettraceGAP() == 1) {
508 for (it.Initialize(LI); it.More(); it.Next()) {
509 cout <<" "<<it.Value()->Geometry();
511 cout <<endl<<" ---->";
515 Standard_Real TolMax = 0,UMin = Precision::Infinite();
516 Standard_Real UMax = -UMin, U;
518 myGapTool->EdgeSupport(I,E);
520 // Construction du nouveau point
521 for (it.Initialize(LI); it.More(); it.Next()) {
522 TopOpeBRepDS_Point PP = myHDS->Point(it.Value()->Geometry());
523 TolMax = Max(TolMax,PP.Tolerance());
524 if (myGapTool->ParameterOnEdge (it.Value(),E,U)) {
528 myGapTool->EdgeSupport(it.Value(),CE);
531 if (TopOpeBRepDS_GettraceGAP() == 1){
532 cout <<"GapFiller : points pas sur la meme edge -> cas non traite"<<endl;
539 BRepAdaptor_Curve C(E); gp_Pnt GP = C.Value(U);
540 TopOpeBRepDS_Point P(GP,TolMax);
543 Standard_Integer IP = myHDS->ChangeDS().AddPoint(P);
545 if (TopOpeBRepDS_GettraceGAP() == 1) {
546 cout <<" New Point : "<<IP<<endl;
549 for (it.Initialize(LI); it.More(); it.Next()) {
550 View.Add(it.Value()->Geometry());
551 myGapTool->SetParameterOnEdge(it.Value(),E,U);
552 myGapTool->SetPoint(it.Value(),IP);
554 myGapTool->SetParameterOnEdge(I,E,U);
555 myGapTool->SetPoint(I,IP);
559 //=======================================================================
560 //function : BuildNewGeometries
562 //=======================================================================
564 void TopOpeBRepDS_GapFiller::BuildNewGeometries()
566 TColStd_MapOfInteger View;
567 Standard_Integer NbCurves = myHDS->NbCurves();
568 Standard_Integer NbPoints = myHDS->NbPoints();
569 for (Standard_Integer i = 1; i <= NbCurves; i++) {
570 TopOpeBRepDS_ListOfInterference& LI = myHDS->ChangeDS().ChangeCurveInterferences(i);
571 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) {
572 Handle(TopOpeBRepDS_Interference) I = it.Value();
573 Standard_Integer IP = I->Geometry();
574 if (View.Add(IP) && IP <= NbPoints) ReBuildGeom(I,View);