0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_FIR.cxx
CommitLineData
b311480e 1// Copyright (c) 1998-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
15// Robert Boehne 30 May 2000 : Dec Osf
16
7fd59977 17#include <BRep_Builder.hxx>
18#include <BRep_Tool.hxx>
42cf5bc1 19#include <BRepAdaptor_Curve.hxx>
20#include <TopExp_Explorer.hxx>
21#include <TopoDS.hxx>
22#include <TopOpeBRepDS_CurvePointInterference.hxx>
7fd59977 23#include <TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State.hxx>
42cf5bc1 24#include <TopOpeBRepDS_define.hxx>
25#include <TopOpeBRepDS_FaceInterferenceTool.hxx>
26#include <TopOpeBRepDS_FIR.hxx>
27#include <TopOpeBRepDS_HDataStructure.hxx>
28#include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
29#include <TopOpeBRepDS_MapOfShapeData.hxx>
30#include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
31#include <TopOpeBRepDS_ShapeData.hxx>
32#include <TopOpeBRepDS_ShapeShapeInterference.hxx>
33#include <TopOpeBRepTool_EXPORT.hxx>
34#include <TopOpeBRepTool_SC.hxx>
7fd59977 35
36#define MDSke TopOpeBRepDS_EDGE
37#define MDSkf TopOpeBRepDS_FACE
38
7fd59977 39Standard_EXPORT Standard_Boolean FUN_Parameters(const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v);
40Standard_EXPORT Standard_Boolean FUN_edgeofface(const TopoDS_Shape& E,const TopoDS_Shape& F);
41
42//------------------------------------------------------
43Standard_Boolean FUN_isPonF(const TopOpeBRepDS_ListOfInterference& LIF,const gp_Pnt& P,const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& E)
44{
45 Standard_Boolean Pok = Standard_True;
46 TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1;
47
48 TopOpeBRepDS_ListIteratorOfListOfInterference itF(LIF);
49 for (;itF.More();itF.Next()) {
50 Handle(TopOpeBRepDS_Interference)& IF = itF.Value(); FDS_data(IF,GT1,G1,ST1,S1);
51 const TopoDS_Face& F = TopoDS::Face(BDS.Shape(S1));
52 TopAbs_Orientation oEinF; Standard_Boolean edonfa = FUN_tool_orientEinFFORWARD(E,F,oEinF );
53 if ( edonfa ) Pok = Standard_True;
54 else {
55 // P est NOK pour une face de LIF : arret
56 Standard_Real u,v; Pok = FUN_Parameters(P,F,u,v);
57 if (!Pok) break;
58 }
59 }
60 return Pok;
61}
62
63//------------------------------------------------------
64Standard_Boolean FUN_findPonF(const TopoDS_Edge& E,const TopOpeBRepDS_DataStructure& BDS, const TopOpeBRepDS_ListOfInterference& LIF,gp_Pnt& P,Standard_Real& par)
65{
66 Standard_Boolean Pok = Standard_False;
67 BRepAdaptor_Curve BAC(E);
68 const TopOpeBRepDS_ListOfInterference& LIE = BDS.ShapeInterferences(E);
69 TopOpeBRepDS_ListIteratorOfListOfInterference itI; itI.Initialize(LIE);
70
71 if ( !itI.More() ) {
72 Pok = FUN_tool_findPinBAC(BAC,P,par);
73 Pok = FUN_isPonF(LIF,P,BDS,E);
74 return Pok;
75 }
76
77 TopOpeBRepDS_Kind GT1,ST1;Standard_Integer G1,S1;
78 for (;itI.More();itI.Next()) {
79 Standard_Boolean pardef = Standard_False;
80
81 Handle(TopOpeBRepDS_Interference)& I = itI.Value(); FDS_data(I,GT1,G1,ST1,S1);
c5f3a425 82 Handle(TopOpeBRepDS_CurvePointInterference) CPI (Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I));
83 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI (Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I));
7fd59977 84 if (!CPI.IsNull()) {
85 par = CPI->Parameter(); pardef = Standard_True;
86 }
87 else if (!SSI.IsNull()) {
88 Standard_Boolean gb = SSI->GBound();
89 if (gb) {
90 const TopoDS_Vertex& V = TopoDS::Vertex(BDS.Shape(G1));
91 P = BRep_Tool::Pnt(V); par = BRep_Tool::Parameter(V,E); pardef = Standard_True;
92 }
93 else {
94 pardef = Standard_False;
95 if (GT1 == TopOpeBRepDS_POINT) P = BDS.Point(G1).Point();
96 else if (GT1 == TopOpeBRepDS_VERTEX) P = BRep_Tool::Pnt(TopoDS::Vertex(BDS.Shape(G1)));
97 if (pardef) {
98 Standard_Real dist; pardef = FUN_tool_projPonC(P,BAC,par,dist);
99 }
100 }
101 }
102 else {
103 continue;
104 }
105
106 if (!pardef) {
107 continue;
108 }
109
110 BAC.D0(par,P);
111 Pok = FUN_isPonF(LIF,P,BDS,E);
112 // P est OK pour toutes les faces de LIF : on arrete de chercher
113 if (Pok) {
114 break;
115 }
116 }
117 return Pok;
118}
119
120// --------------------------------------------------------
536a3cb8 121static void FDS_ADDEDGE (const Standard_Boolean
122 , const TCollection_AsciiString&
123 , const Standard_Integer
7fd59977 124 ,TopOpeBRepDS_FaceInterferenceTool& FITool
125 ,const TopoDS_Shape& FI
126 ,const TopoDS_Shape& F
127 ,const TopoDS_Shape& Ecpx
128 ,const Standard_Boolean isEGsp
129 ,const Handle(TopOpeBRepDS_Interference)& I
130)
131{
7fd59977 132 FITool.Add(FI,F,Ecpx,isEGsp,I);
7fd59977 133}
134
135//------------------------------------------------------
136// EGsp = edge splittee de iEG ( Null si iEG n'est pas splittee)
137void FUN_reduceEDGEgeometry1
138(TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer iFI,const Standard_Integer iEG,const TopoDS_Shape& EGsp,
139// const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp)
140 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& )
141{
142 Standard_Boolean TRCF = Standard_False;
7fd59977 143 TopOpeBRepDS_ListIteratorOfListOfInterference ili(LI); if (!ili.More()) return;
144
145 // choix de l'arete Ecpx, lieu de resolution de la transition complexe
146 const TopoDS_Face& FI = TopoDS::Face(BDS.Shape(iFI));
147 Standard_Boolean isEGsp = (! EGsp.IsNull());
148 TopoDS_Edge Ecpx;
149 if (isEGsp) Ecpx = TopoDS::Edge(EGsp);
150 else Ecpx = TopoDS::Edge(BDS.Shape(iEG));
151
152 TopOpeBRepDS_PDataStructure pbds = (TopOpeBRepDS_PDataStructure)(void*)&BDS;
153 TopOpeBRepDS_FaceInterferenceTool FITool(pbds);
154 gp_Pnt Pok; Standard_Boolean isPok = Standard_False; Standard_Real parPok;
155 if ( LI.Extent() >= 2) {
156 if ( isEGsp ) isPok = FUN_tool_findPinE(Ecpx,Pok,parPok);
157 else isPok = FUN_findPonF(Ecpx,BDS,LI,Pok,parPok); // NYI pas necessaire
158 if (!isPok) { LI.Clear(); return; }
159 FITool.SetEdgePntPar(Pok,parPok);
160 }
161
162 // xpu :090498 :
163 // CTS20205 : sp(e5) = sp(e4 of rank=1) and c3d(e5) c3d(e4) are diff oriented
164 // As transitions on face<iFI> are given relative to the geometry of e5,
165 // we have to complement them.
166// Standard_Boolean toreverse = Standard_False;
167// Standard_Boolean hsdm = !BDS.ShapeSameDomain(iEG).IsEmpty();
168// if (hsdm) {
169// Standard_Boolean sameoriented = Standard_False;
170// Standard_Boolean ok = FUN_tool_curvesSO(TopoDS::Edge(Ecpx),parPok,TopoDS::Edge(BDS.Shape(iEG)),
171// sameoriented);
172// if (ok) toreverse = !sameoriented;
173// }
174 // xpu :090498
175
176 // FI = face de reference (shape), iFI (indice)
177 // E = arete geometrie d'interference (shape), iEG (indice)
178 // LI = liste d'interf de geom iEG et dont les Support() sont a transitionner complexe
179
180 Handle(TopOpeBRepDS_Interference) I1,I2; TopOpeBRepDS_Kind GT1,ST1,GT2,ST2; Standard_Integer G1,S1,G2,S2;
181 TopOpeBRepDS_ListIteratorOfListOfInterference it1; it1.Initialize(LI);
182 while (it1.More()) {
183 Standard_Boolean u1 = FDS_data(it1,I1,GT1,G1,ST1,S1);if (u1) {it1.Next();continue;}
184 Standard_Boolean ya1 = (GT1 == MDSke); if (!ya1) {it1.Next();continue;}
185
186 Standard_Boolean isComplex = Standard_False; // True if at least two interfs on the same edge
187 const TopoDS_Face& F1 = TopoDS::Face(BDS.Shape(S1));
188
189 TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1); it2.Next();
190 while (it2.More()) {
191 Standard_Boolean u2 = FDS_data(it2,I2,GT2,G2,ST2,S2);if (u2) {it2.Next();continue;}
192 Standard_Boolean ya2 = (GT2==GT1 && G2==G1 && ST2==ST1); if (!ya2) {it2.Next();continue;}
193 const TopoDS_Face& F2 = TopoDS::Face(BDS.Shape(S2));
194 if (!isComplex) {
195 isComplex = Standard_True;
196
197
198// TopOpeBRepDS_Transition T1 = I1->Transition(); TopAbs_Orientation O1 = T1.Orientation(TopAbs_IN); // xpu :090498
199// Standard_Boolean revT1 = toreverse && (M_FORWARD(O1) || M_REVERSED(O1)); // xpu :090498
7fd59977 200// if (revT1) I1->ChangeTransition() = T1.Complement(); //xpu :090498
201 FITool.Init(FI,Ecpx,isEGsp,I1);
202 FDS_ADDEDGE(TRCF,"\ninit transition complexe F",iFI,FITool,FI,F1,Ecpx,isEGsp,I1);
203// if (revT1) I1->ChangeTransition() = T1.Complement(); //xpu :090498
204 }
205
206// TopOpeBRepDS_Transition T2 = I2->Transition(); TopAbs_Orientation O2 = T2.Orientation(TopAbs_IN); // xpu :090498
207// Standard_Boolean revT2 = toreverse && (M_FORWARD(O2) || M_REVERSED(O2)); // xpu :090498
7fd59977 208// if (revT2) I2->ChangeTransition() = T2.Complement(); //xpu :090498
209 FDS_ADDEDGE(TRCF,"add transition complexe F",iFI,FITool,FI,F2,Ecpx,isEGsp,I2);
210// if (revT2) I2->ChangeTransition() = T2.Complement(); //xpu :090498
211
212 LI.Remove(it2);
213 }
214 if (isComplex) {
215 FITool.Transition(I1);
7fd59977 216 }
217 it1.Next();
218 } // it1.More()
219} // FUN_reduceEDGEgeometry1
220
221//------------------------------------------------------
222void FUN_GmapS(TopOpeBRepDS_ListOfInterference& LI, const TopOpeBRepDS_DataStructure& BDS, TopOpeBRepDS_MapOfShapeData& mosd)
223{
224 mosd.Clear();
225 TopOpeBRepDS_Kind GT1,ST1;Standard_Integer G1,S1;
226 for (TopOpeBRepDS_ListIteratorOfListOfInterference it1(LI);it1.More();it1.Next()) {
227 Handle(TopOpeBRepDS_Interference)& I1=it1.Value(); FDS_data(I1,GT1,G1,ST1,S1);
228 if ( GT1 != MDSke || ST1 != MDSkf ) continue;
229 const TopoDS_Shape& SG1 = BDS.Shape(G1);
230 TopOpeBRepDS_ShapeData thedata;
231 if (!mosd.Contains(SG1)) mosd.Add(SG1, thedata);
232 mosd.ChangeFromKey(SG1).ChangeInterferences().Append(I1);
233 }
234}
235
236//------------------------------------------------------
237TopAbs_State FUN_stateedgeface(const TopoDS_Shape& E, const TopoDS_Shape& F, gp_Pnt& P)
238{
239 TopAbs_State state = TopAbs_UNKNOWN;
240 Standard_Real par; FUN_tool_findPinE(E,P,par);
241 Standard_Real u,v; Standard_Boolean Pok = FUN_Parameters(P,F,u,v);
242 if (Pok) { // classifier u,v dans F
243 TopOpeBRepTool_ShapeClassifier& PSC = FSC_GetPSC(F);
244 gp_Pnt2d Puv(u,v);
245 PSC.StateP2DReference(Puv);
246 state = PSC.State();
247 }
248 return state;
249}
250
251#define M_IN(ssstate) ((ssstate) == TopAbs_IN)
252#define M_ON(ssstate) ((ssstate) == TopAbs_ON)
253#define M_OUT(ssstate) ((ssstate) == TopAbs_OUT)
254#define M_UNK(ssstate) ((ssstate) == TopAbs_UNK)
255
256//------------------------------------------------------
257void FUN_reduceEDGEgeometry
258(TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer iFI,
259const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp)
260{
261 if (!LI.Extent()) return;
262
263 TopOpeBRepDS_MapOfShapeData mosd;
264 FUN_GmapS(LI,BDS,mosd);
265
7fd59977 266 TopOpeBRepDS_ListOfInterference LIout;
267 //modified by NIZNHY-PKV Thu Mar 16 09:44:24 2000 f
268 Standard_Integer i, aN;
269 aN=mosd.Extent();
270 //for(Standard_Integer i=1,n=mosd.Extent(); i<=n; i++) {
271 //modified by NIZNHY-PKV Thu Mar 16 09:44:27 2000 t
272 for(i=1 ; i<=aN; i++) {
273 const TopoDS_Shape& EG = mosd.FindKey(i);
274 Standard_Integer iEG = BDS.Shape(EG);
275
276 // donnees samedomain attachees a l'arete iEG
277 const TopTools_ListOfShape& esdeg = BDS.ShapeSameDomain(iEG);
278 Standard_Boolean egissect = BDS.IsSectionEdge(TopoDS::Edge(EG));
279 Standard_Boolean eghasesd = (! esdeg.IsEmpty());
280
7fd59977 281 TopOpeBRepDS_ListOfInterference& LIEG = mosd.ChangeFromKey(EG).ChangeInterferences();
282 Standard_Integer nExt = LIEG.Extent();
283 // LIEG = toutes les interferences dont le Support() est une
284 // face possedant une interference dont la Geometry() est EG.
7fd59977 285 if (nExt == 0) {
286 continue;
287 }
288 if (nExt == 1) {
289 LIout.Append(LIEG);
290 }
291
292 else if (nExt >= 2) {
293 Standard_Boolean isEGsp = MEsp.IsBound(EG);
294 //modified by NIZNHY-PKV Thu Mar 16 11:03:44 2000 from
295 //Standard_Integer nEGsp = 0;
296 //modified by NIZNHY-PKV Thu Mar 16 11:03:49 2000 to
297 if (isEGsp) {
298 const TopOpeBRepDS_ListOfShapeOn1State& los1 = MEsp.Find(EG);
299 isEGsp = los1.IsSplit();
300 //modified by NIZNHY-PKV Thu Mar 16 11:02:40 2000 from
301 //if ( isEGsp ) {
302 // const TopTools_ListOfShape& los = los1.ListOnState();
303 // nEGsp = los.Extent();
304 //}
305 //modified by NIZNHY-PKV Thu Mar 16 11:02:46 2000 to
306 }
307
308 if ( isEGsp ) {
309 const TopTools_ListOfShape& los = MEsp.Find(EG).ListOnState();
310 TopTools_ListIteratorOfListOfShape itlos(los);
311 for(;itlos.More();itlos.Next()) {
312 // EGsp est une arete splitee de EG.
313 const TopoDS_Shape& EGsp = itlos.Value();
314
315 // LISFIN = liste des interferences de LI dont le Support()
316 // est une face contenant geometriquement l'arete EGsp
317 TopOpeBRepDS_ListOfInterference LISFIN;
318 TopOpeBRepDS_ListIteratorOfListOfInterference itLIEG(LIEG);
319 for(; itLIEG.More(); itLIEG.Next()) {
320 const Handle(TopOpeBRepDS_Interference)& ILIEG = itLIEG.Value();
321 Standard_Integer iS = ILIEG->Support();
322 TopOpeBRepDS_Kind kS = ILIEG->SupportType();
323 if ( kS == MDSkf ) {
324 const TopoDS_Shape& SFILIEG = BDS.Shape(iS);
325 gp_Pnt P;
326 TopAbs_State staef = FUN_stateedgeface(EGsp,SFILIEG,P);
327
328 Standard_Boolean Pok = M_IN(staef);
329 if ( eghasesd || egissect ) {
330 Pok = Pok || M_ON(staef);
331 }
332
333 if (Pok) {
334 LISFIN.Append(ILIEG);
335 }
336 }
337 } // itLIEG.More
338
339 Standard_Integer nLISFIN = LISFIN.Extent();
340 if (nLISFIN >= 2 ) {
341 Standard_Boolean gb;
342 gb = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(LISFIN.First())->GBound();
343
344 if (gb) {
345 //modified by NIZNHY-PKV Thu Mar 16 10:40:57 2000 f
346 // we have to rest at least one Interference on the face.
347 // To kill all of them is too bravely.
348 Handle(TopOpeBRepDS_Interference) anInterference = LISFIN.First();
349 LISFIN.Clear();
350 LISFIN.Append(anInterference);
351 //modified by NIZNHY-PKV Thu Mar 16 10:41:01 2000 t
352 }
353 else
354 FUN_reduceEDGEgeometry1(LISFIN,BDS,iFI,iEG,EGsp,MEsp);
355 }
356
357 nLISFIN = LISFIN.Extent();
358 if (nLISFIN)
359 LIout.Append(LISFIN);
360 }
361 } // isEGsp
362 else {
363 // iFI = face de reference (indice)
364 // E = arete geometrie d'interference (shape), iEG (indice)
365 // LIEG = liste d'interferences de geometrie EG
366 // et dont les Support() sont a transitionner complexe
367 TopoDS_Shape Enull;
368 FUN_reduceEDGEgeometry1(LIEG,BDS,iFI,iEG,Enull,MEsp);
369 LIout.Append(LIEG);
370 }
371 }
372 }
373
374 LI.Clear();
375 LI.Append(LIout);
376} // FUN_reduceEDGEgeometry
377
378//=======================================================================
379//function : TopOpeBRepDS_FIR
380//purpose :
381//=======================================================================
382TopOpeBRepDS_FIR::TopOpeBRepDS_FIR
383(const Handle(TopOpeBRepDS_HDataStructure)& HDS) : myHDS(HDS)
384{}
385
386//=======================================================================
387//function : ProcessFaceInterferences
388//purpose :
389//=======================================================================
390void TopOpeBRepDS_FIR::ProcessFaceInterferences(const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& M)
391{
392 TopOpeBRepDS_DataStructure& BDS = myHDS->ChangeDS();
393 Standard_Integer i,nshape = BDS.NbShapes();
394 for (i = 1; i <= nshape; i++) {
395 const TopoDS_Shape& S = BDS.Shape(i);
396 if(S.IsNull()) continue;
397 if ( S.ShapeType() == TopAbs_FACE ) {
398 ProcessFaceInterferences(i,M);
399 }
400 }
401}
402
403//=======================================================================
404//function : ProcessFaceInterferences
405//purpose :
406//=======================================================================
407void TopOpeBRepDS_FIR::ProcessFaceInterferences
408(const Standard_Integer SIX,const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp)
409{
410 TopOpeBRepDS_DataStructure& BDS = myHDS->ChangeDS();
7fd59977 411 TopOpeBRepDS_ListOfInterference& LI = BDS.ChangeShapeInterferences(SIX);
412 TopOpeBRepDS_ListOfInterference lw, lE, lFE, lFEF, lF; lw.Assign(LI);
413
96a95605
DB
414 ::FUN_selectTRASHAinterference(lw,TopAbs_FACE,lF);
415 ::FUN_selectGKinterference(lF,MDSke,lFE);
416 ::FUN_selectSKinterference(lFE,MDSkf,lFEF);
417 ::FUN_selectTRASHAinterference(lw,TopAbs_EDGE,lE);
7fd59977 418 FUN_reduceEDGEgeometry(lFEF,BDS,SIX,MEsp);
419
7fd59977 420 LI.Clear();
421 LI.Append(lF);
422 LI.Append(lFE);
423 LI.Append(lFEF);
424 LI.Append(lE);
425 // MSV: filter duplicates
426 ::FUN_reducedoublons(LI,BDS,SIX);
427}