0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_GapFiller.cxx
CommitLineData
b311480e 1// Created on: 1998-08-19
2// Created by: Yves FRICAUD
3// Copyright (c) 1998-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <TopOpeBRepDS_GapFiller.ixx>
18#include <TopExp_Explorer.hxx>
19#include <TopoDS.hxx>
20#include <TopoDS_Shape.hxx>
21#include <TopAbs_ShapeEnum.hxx>
22#include <TopTools_ListIteratorOfListOfShape.hxx>
23#include <TopOpeBRepDS_ListIteratorOfListOfInterference.hxx>
24#include <Precision.hxx>
25#include <TopOpeBRepDS_connex.hxx>
26#include <TopOpeBRepDS_Point.hxx>
27#include <TColgp_SequenceOfPnt.hxx>
28#include <TColStd_MapOfTransient.hxx>
29
30#include <BRepAdaptor_Curve.hxx>
31#include <BRepAdaptor_Surface.hxx>
32
33#include <gp.hxx>
34#include <gp_Pnt.hxx>
35#include <gp_Pln.hxx>
36#include <gp_Dir.hxx>
37#include <gp_Vec.hxx>
38
39#include <Geom2d_Curve.hxx>
40
0797d9d3 41#ifdef OCCT_DEBUG
1d0a9d4d 42extern Standard_Boolean TopOpeBRepDS_GettraceGAP();
43extern Standard_Boolean TopOpeBRepDS_GetcontextNOGAP();
7fd59977 44#endif
45
46//=======================================================================
47//function : TopOpeBRepDS_GapFiller
48//purpose :
49//=======================================================================
50
51TopOpeBRepDS_GapFiller::TopOpeBRepDS_GapFiller(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
52:myHDS(HDS)
53{
54 myGapTool = new TopOpeBRepDS_GapTool(HDS);
55 myAsso = new TopOpeBRepDS_Association();
56}
57
58
59//=======================================================================
60//function : Perform
61//purpose :
62//=======================================================================
63
64void TopOpeBRepDS_GapFiller::Perform()
65{
66
0797d9d3 67#ifdef OCCT_DEBUG
7fd59977 68 if (TopOpeBRepDS_GetcontextNOGAP () != 0) return;
69#endif
70
71 myGapTool->Init(myHDS);
72 TColStd_MapOfInteger View;
73 //------------------------------------------------------------
74 // APPAIRAGE ...
75 //------------------------------------------------------------
76 Standard_Integer NbCurves = myHDS->NbCurves();
77 for (Standard_Integer i = 1; i <= NbCurves; i++) {
78 TopOpeBRepDS_ListOfInterference& LI = myHDS->ChangeDS().ChangeCurveInterferences(i);
79 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) {
80 TopOpeBRepDS_ListOfInterference ALI;
81 const Handle(TopOpeBRepDS_Interference)& I = it.Value();
82 if (I->GeometryType() == TopOpeBRepDS_POINT) {
83 if (View.Add(I->Geometry())) {
84 FindAssociatedPoints (I,ALI);
85 myAsso->Associate(I,ALI);
86 }
87 }
88 }
89 }
90 //--------------------------------------------------------
91 // Modification des Geometries
92 //--------------------------------------------------------
93 BuildNewGeometries();
94}
95
96//=======================================================================
97//function : Contains
98//purpose :
99//=======================================================================
100
101Standard_Boolean Contains (const TopoDS_Shape& F,const TopoDS_Shape& E)
102{
103 TopExp_Explorer exp;
104 for (exp.Init(F,E.ShapeType()); exp.More(); exp.Next()){
105// for (TopExp_Explorer exp(F,E.ShapeType()); exp.More(); exp.Next()){
106 if (exp.Current().IsSame(E)) return 1;
107 }
108 return 0;
109}
110
111
112//=======================================================================
113//function : FindAssociatedPoints
114//purpose :
115//=======================================================================
116
117void TopOpeBRepDS_GapFiller::FindAssociatedPoints(const Handle(TopOpeBRepDS_Interference)& I,
118 TopOpeBRepDS_ListOfInterference& LI)
119{
120 TopOpeBRepDS_ListIteratorOfListOfInterference itSI(myGapTool->SameInterferences(I));
121 for (; itSI.More();itSI.Next()){
122 if (myAsso->HasAssociation(itSI.Value())) return;
123 }
124
0797d9d3 125#ifdef OCCT_DEBUG
7fd59977 126 if (TopOpeBRepDS_GettraceGAP() == 1) {
127 cout<<endl;
128 cout<<"-----------------------------------------------------"<<endl;
129 cout<<" Association Point "<<I->Geometry()<<endl;
130 }
131#endif
132
133 //------------------------------------------------------------------------
134 // PREMIERE PASSE : Recherche de l association parmi les points qui sont:
135 // - sur la meme arete
136 // - sur l autre face connexe a l arete.
137 // - Dans la meme face coupante.
138 //------------------------------------------------------------------------
139 //----------------------------------------------
140 // LI = { ensemble des interference sur l'arete}
141 //----------------------------------------------
142 TopoDS_Shape E ;
143 if (!myGapTool->EdgeSupport(I,E)) {
144 return;
145 }
146 AddPointsOnShape(E,LI);
147
148 TopoDS_Face F1,F2,F;
149 if (!myGapTool->FacesSupport(I,F1,F2)) {
150 LI.Clear(); return;
151 }
152
153 if (!Contains(F1,E)) {F = F2; F2 = F1; F1 = F;}
154
155 const TopTools_ListOfShape& LF = FDSCNX_EdgeConnexitySameShape(E,myHDS);
156 //------------------------------------------------------------------------
157 // Si le point de I est sur deux faces connexes a E => connexite des sections
158 // => pas d association a faire.
159 //------------------------------------------------------------------------
160// for (TopTools_ListIteratorOfListOfShape itLF(LF); itLF.More(); itLF.Next()) {
161 TopTools_ListIteratorOfListOfShape itLF(LF) ;
162 for ( ; itLF.More(); itLF.Next()) {
163 if (!itLF.Value().IsSame(F1)) {
164 if (IsOnFace(I,TopoDS::Face(itLF.Value()))) {
165 LI.Clear(); return;
166 }
167 }
168 }
169
170 //------------------------------------------------------------------------
171 // LI = { ensemble des interference sur l'arete && sur une autre section ds
172 // la Face connexe par E}
173 //------------------------------------------------------------------------
174
175 for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
176 if (!itLF.Value().IsSame(F1)) {
177 FilterByFace(TopoDS::Face(itLF.Value()),LI);
178 }
179 }
180 //--------------------------------------------
181 // LI = LI && point dans la meme face Support2
182 //--------------------------------------------
183 if (!LI.IsEmpty())
184 FilterByFace (F2, LI);
185
186 //-------------------------------
187 // Controle et Selection metrique
188 //-------------------------------
189 if (!LI.IsEmpty())
190 FilterByIncidentDistance (F2,I,LI);
191
192 if (!LI.IsEmpty()) {
193 LI.Append(I);
194 }
195
0797d9d3 196#ifdef OCCT_DEBUG
7fd59977 197 if (TopOpeBRepDS_GettraceGAP() != 0) {
198 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
199 for (it.Initialize(LI); it.More(); it.Next()) {
200 cout<<" "<<it.Value()->Geometry();
201 }
202 cout<<endl;
203 }
204#endif
205 }
206
207
208//=======================================================================
209//function : CheckConnexity
210//purpose :
211//=======================================================================
212
213//Standard_Boolean TopOpeBRepDS_GapFiller::CheckConnexity(TopOpeBRepDS_ListOfInterference& LI)
214Standard_Boolean TopOpeBRepDS_GapFiller::CheckConnexity(TopOpeBRepDS_ListOfInterference& )
215{
216 return 1;
217}
218
219//=======================================================================
220//function : AddPointsOnFace
221//purpose :
222//=======================================================================
223
224void TopOpeBRepDS_GapFiller::AddPointsOnShape (const TopoDS_Shape& S,
225 TopOpeBRepDS_ListOfInterference& LI)
226{
227 const TopOpeBRepDS_ListOfInterference& LIOnE = myHDS->DS().ShapeInterferences(S);
228 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LIOnE); it.More(); it.Next()){
229 LI.Append(it.Value());
230 }
231}
232
233//=======================================================================
234//function : AddPointsOnConnexShape
235//purpose :
236//=======================================================================
237
238//void TopOpeBRepDS_GapFiller::AddPointsOnConnexShape(const TopoDS_Shape& // F,
239// const TopOpeBRepDS_ListOfInterference& LI)
240void TopOpeBRepDS_GapFiller::AddPointsOnConnexShape(const TopoDS_Shape& ,
241 const TopOpeBRepDS_ListOfInterference& )
242{
243}
244
245
246//=======================================================================
247//function : FilterbyFace
248//purpose :
249//=======================================================================
250
251void TopOpeBRepDS_GapFiller::FilterByFace(const TopoDS_Face& F,
252 TopOpeBRepDS_ListOfInterference& LI)
253{
254 //------------------------------------------------------------------------
255 // il ne restera dans LI que les interference dont une des representation
256 // a ete calculee sur F .
257 //------------------------------------------------------------------------
258 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
259 while (it.More()) {
260 if (!IsOnFace(it.Value(),F)) {
261 LI.Remove(it);
262 }
263 else {
264 it.Next();
265 }
266 }
267}
268
269//=======================================================================
270//function : IsOnFace
271//purpose :
272//=======================================================================
273
274Standard_Boolean TopOpeBRepDS_GapFiller::IsOnFace
275(const Handle(TopOpeBRepDS_Interference)& I,
276 const TopoDS_Face& F) const
277{
278 TopOpeBRepDS_Curve C;
279 if (myGapTool->Curve(I,C)) {
280 TopoDS_Shape S1,S2;
281 C.GetShapes(S1,S2);
282 if (S1.IsSame(F)) return 1;
283 if (S2.IsSame(F)) return 1;
284 }
285 return 0;
286}
287
288
289//=======================================================================
290//function : FilterbyEdge
291//purpose :
292//=======================================================================
293
294void TopOpeBRepDS_GapFiller::FilterByEdge(const TopoDS_Edge& E,
295 TopOpeBRepDS_ListOfInterference& LI)
296{
297 // il ne restera dans LI que les interference dont une des representation
298 // a pour support E
299 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
300 while (it.More()) {
301 if (!IsOnEdge(it.Value(),E)) {
302 LI.Remove(it);
303 }
304 else {
305 it.Next();
306 }
307 }
308}
309
310//=======================================================================
311//function : IsOnEdge
312//purpose :
313//=======================================================================
314
315Standard_Boolean TopOpeBRepDS_GapFiller::IsOnEdge
316(const Handle(TopOpeBRepDS_Interference)& I,
317 const TopoDS_Edge& E) const
318{
319 const TopOpeBRepDS_ListOfInterference& LI = myGapTool->SameInterferences(I);
320 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) {
321 const Handle(TopOpeBRepDS_Interference)& IC = it.Value();
322 if (IC->SupportType() == TopOpeBRepDS_EDGE) {
323 const TopoDS_Shape& S1 = myHDS->Shape(IC->Support());
324 if (S1.IsSame(E)) return 1;
325 }
326 }
327 return 0;
328}
329
330
331
332//=======================================================================
333//function : Normale
334//purpose :
335//=======================================================================
336
337static Standard_Boolean Normal(const Handle(TopOpeBRepDS_GapTool)& A,
338 const Handle(TopOpeBRepDS_HDataStructure)& HDS,
339 const Handle(TopOpeBRepDS_Interference)& I,
340 const TopoDS_Face& F,
341 gp_Dir& D)
342
343{
344 TopOpeBRepDS_Kind GK,SK;
345 Standard_Integer IG,IS;
346 gp_Pnt PS;
347 gp_Vec TU,TV,N;
348 gp_Pnt2d P2d;
349
350 BRepAdaptor_Surface S(F);
351 if (S.GetType() == GeomAbs_Plane) {
352 D = S.Plane().Axis().Direction();
353 return 1;
354 }
355
356 const TopOpeBRepDS_ListOfInterference& LI = A->SameInterferences(I);
357 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) {
358 const Handle(TopOpeBRepDS_Interference)& IC = it.Value();
359 IC->GKGSKS(GK,IG,SK,IS);
360 if (SK == TopOpeBRepDS_CURVE) {
361 const TopOpeBRepDS_Curve& C = HDS->Curve(IS);
c5f3a425 362 Standard_Real P = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast (IC)->Parameter();
7fd59977 363
364 TopoDS_Shape S1,S2;
365 C.GetShapes(S1,S2);
366 if (F.IsSame(S1)) {
367 if (C.Curve1().IsNull()) return 0;
368 P2d = C.Curve1()->Value(P);
369 }
370 else {
371 if (C.Curve2().IsNull()) return 0;
372 P2d = C.Curve2()->Value(P);
373 }
374
375 if (S.UContinuity() >= GeomAbs_C1 && S.VContinuity() >= GeomAbs_C1) {
376 S.D1(P2d.X(),P2d.Y(),PS,TU,TV);
377 N = TU^TV;
378// if (N.SquareMagnitude() >= gp::Resolution()); { // !!
379 if (N.SquareMagnitude() >= gp::Resolution()) {
380 D = gp_Dir(N);
381 return 1;
382 }
383 }
384 return 0;
385 }
386 }
387 return 0;
388}
389
390//=======================================================================
391//function : FilterByIncidentDistance
392//purpose :
393//=======================================================================
394
395void TopOpeBRepDS_GapFiller::FilterByIncidentDistance(const TopoDS_Face& F,
396 const Handle(TopOpeBRepDS_Interference)& I,
397 TopOpeBRepDS_ListOfInterference& LI)
398{
399 Standard_Real DistMin = Precision::Infinite();
400 Handle(TopOpeBRepDS_Interference) ISol;
401
402 const TopOpeBRepDS_Point& PI1 = myHDS->Point(I->Geometry());
403 const gp_Pnt GPI = PI1.Point();
404
405 BRepAdaptor_Surface S(F,0);
406
407 Standard_Real TolDef = 0.94;// cos(20degre);
408 Standard_Real TolDist = 20*PI1.Tolerance();
409 gp_Dir N1,N2;
410 Standard_Boolean Ok1 = Normal(myGapTool,myHDS,I,F,N1);
411
412 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);it.More(); it.Next()) {
413
414 const Handle(TopOpeBRepDS_Interference)& CI = it.Value();
415
416 if (CI->HasSameGeometry(I)) continue;
417
418 Standard_Boolean Ok2 = Normal(myGapTool,myHDS,CI,F,N2);
419 const TopOpeBRepDS_Point& P = myHDS->Point((CI->Geometry()));
420 const gp_Pnt GP = P.Point();
421 Standard_Real Dist = GP.Distance(GPI);
422
423 //---------------------------------------------------------------------------
424 // Test resjection
425 // Si les points sont plutot ecartes, on regarde si les Normales sur la face
426 // sont proches
427 //---------------------------------------------------------------------------
428 if (Dist > TolDist) {
429 if (Ok1 && Ok2) {
430 if (N1.Dot(N2) < TolDef) {
431 continue; // Reject
432 }
433 }
434 continue; // Reject
435 }
436
437 if (Dist < DistMin) {
438 DistMin = Dist;
439 ISol = it.Value();
440 }
441 }
442
443 LI.Clear();
444 if (!ISol.IsNull()) {
445 LI.Append(ISol);
0797d9d3 446#ifdef OCCT_DEBUG
7fd59977 447 if (TopOpeBRepDS_GettraceGAP() == 1){
448 cout << " Distance Minimum :"<<DistMin<<endl;
449 }
450#endif
451 }
452}
453
454//=======================================================================
455//function : BuildNewPoint
456//purpose :
457//=======================================================================
458//unreferenced function, commented
459/*
0797d9d3 460#ifdef OCCT_DEBUG
7fd59977 461static void BuildNewPoint (const TColgp_SequenceOfPnt& LP,
462 const Standard_Real& TolMax,
463 TopOpeBRepDS_Point& Point)
464{
465 if (LP.IsEmpty()) return;
466 Standard_Real xp = 0.,yp = 0.,zp = 0.;
467
468 Standard_Integer i,Nb = LP.Length();
469 for (i = 1; i <= Nb; i++) {
470 const gp_Pnt& CP = LP(i);
471 xp+= CP.X();yp+=CP.Y();zp+=CP.Z();
472 }
473 xp/=Nb;yp/=Nb;zp/=Nb;
474 gp_Pnt NP(xp,yp,zp);
475
476 Standard_Real DistMax = 0;
477 for (i = 1; i <= Nb; i++) {
478 const gp_Pnt& CP = LP(i);
479 DistMax = Max(CP.Distance(NP),DistMax);
480 }
481 Point.ChangePoint() = NP;
482 Point.Tolerance(DistMax+TolMax);
483}
484#endif
485*/
486//=======================================================================
487//function : ReBuildGeom
488//purpose :
489//=======================================================================
490
491void TopOpeBRepDS_GapFiller::ReBuildGeom(const Handle(TopOpeBRepDS_Interference)& I,
492 TColStd_MapOfInteger& View)
493{
494 if (!myAsso->HasAssociation(I)) return;
495
496 TopOpeBRepDS_ListOfInterference& LI = myAsso->Associated(I);
497 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
498
0797d9d3 499#ifdef OCCT_DEBUG
7fd59977 500 if (TopOpeBRepDS_GettraceGAP() == 1) {
501 cout <<"Points ";
502 for (it.Initialize(LI); it.More(); it.Next()) {
503 cout <<" "<<it.Value()->Geometry();
504 }
505 cout <<endl<<" ---->";
506 }
507#endif
508
509 Standard_Real TolMax = 0,UMin = Precision::Infinite();
510 Standard_Real UMax = -UMin, U;
511 TopoDS_Edge E,CE ;
512 myGapTool->EdgeSupport(I,E);
513
514 // Construction du nouveau point
515 for (it.Initialize(LI); it.More(); it.Next()) {
516 TopOpeBRepDS_Point PP = myHDS->Point(it.Value()->Geometry());
517 TolMax = Max(TolMax,PP.Tolerance());
518 if (myGapTool->ParameterOnEdge (it.Value(),E,U)) {
519 UMin = Min(UMin,U);
520 UMax = Max(UMax,U);
521 }
522 myGapTool->EdgeSupport(it.Value(),CE);
523 if (!CE.IsSame(E)) {
0797d9d3 524#ifdef OCCT_DEBUG
7fd59977 525 if (TopOpeBRepDS_GettraceGAP() == 1){
526 cout <<"GapFiller : points pas sur la meme edge -> cas non traite"<<endl;
527 }
528#endif
529 return;
530 }
531 }
532 U = (UMax+UMin)*0.5;
533 BRepAdaptor_Curve C(E); gp_Pnt GP = C.Value(U);
534 TopOpeBRepDS_Point P(GP,TolMax);
535
536 // Mise a jour.
537 Standard_Integer IP = myHDS->ChangeDS().AddPoint(P);
0797d9d3 538#ifdef OCCT_DEBUG
7fd59977 539 if (TopOpeBRepDS_GettraceGAP() == 1) {
540 cout <<" New Point : "<<IP<<endl;
541 }
542#endif
543 for (it.Initialize(LI); it.More(); it.Next()) {
544 View.Add(it.Value()->Geometry());
545 myGapTool->SetParameterOnEdge(it.Value(),E,U);
546 myGapTool->SetPoint(it.Value(),IP);
547 }
548 myGapTool->SetParameterOnEdge(I,E,U);
549 myGapTool->SetPoint(I,IP);
550 View.Add(IP);
551}
552
553//=======================================================================
554//function : BuildNewGeometries
555//purpose :
556//=======================================================================
557
558void TopOpeBRepDS_GapFiller::BuildNewGeometries()
559{
560 TColStd_MapOfInteger View;
561 Standard_Integer NbCurves = myHDS->NbCurves();
562 Standard_Integer NbPoints = myHDS->NbPoints();
563 for (Standard_Integer i = 1; i <= NbCurves; i++) {
564 TopOpeBRepDS_ListOfInterference& LI = myHDS->ChangeDS().ChangeCurveInterferences(i);
565 for (TopOpeBRepDS_ListIteratorOfListOfInterference it(LI); it.More(); it.Next()) {
566 Handle(TopOpeBRepDS_Interference) I = it.Value();
567 Standard_Integer IP = I->Geometry();
568 if (View.Add(IP) && IP <= NbPoints) ReBuildGeom(I,View);
569 }
570 }
571}
572
573