Salome HOME
Synchronize adm files
[modules/hexablock.git] / src / HEXABLOCKGUI / HEXABLOCKGUI_SalomeTools.cxx
1 // Copyright (C) 2009-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <set>
21
22
23 #include <BRepTools.hxx>
24
25
26 // VTK includes
27 #include <vtkRenderer.h>
28 #include <vtkActorCollection.h>
29 #include <vtkUnstructuredGrid.h>
30
31
32
33 #include <SUIT_Session.h>
34
35 #include <SalomeApp_Study.h>
36 #include <SalomeApp_Application.h>
37
38 #include <OCCViewer_ViewWindow.h>
39
40 #include <SVTK_ViewManager.h>
41 #include <SVTK_ViewModel.h>
42 #include <SVTK_ViewWindow.h>
43 #include <SVTK_Prs.h>
44 #include <SALOME_Actor.h>
45 #include <VTKViewer_Algorithm.h>
46
47 #include <SelectMgr_Selection.hxx>
48 #include <TColStd_ListIteratorOfListOfInteger.hxx>
49 #include <SelectBasics_SensitiveEntity.hxx>
50 #include <TColStd_IndexedMapOfInteger.hxx>
51 #include <TopTools_IndexedMapOfShape.hxx>
52 #include <TopExp.hxx>
53 #include <StdSelect_BRepOwner.hxx>
54
55 #include <TopoDS.hxx>
56 #include <TopoDS_Face.hxx>
57 #include <BRepBuilderAPI_MakeVertex.hxx>
58 #include <Geom_Surface.hxx>
59 #include <ShapeAnalysis.hxx>
60 #include <BRep_Tool.hxx>
61 #include <BRep_Builder.hxx>
62 #include <Geom_Curve.hxx>
63 #include <BRepExtrema_DistShapeShape.hxx>
64 #include <BRepAdaptor_Curve.hxx>
65 #include <GCPnts_AbscissaPoint.hxx>
66 #include <TopoDS_Compound.hxx>
67
68 #include "HEXABLOCKGUI.hxx"
69 #include "HEXABLOCKGUI_SalomeTools.hxx"
70 #include "HEXABLOCKGUI_OccGraphicView.hxx"
71
72
73
74 //#define _DEVDEBUG_
75 using namespace std;
76
77 namespace HEXABLOCK
78 {
79 namespace GUI
80 {
81
82         SUIT_Study* GetActiveStudy()
83         {
84                 SUIT_Application* app = SUIT_Session::session()->activeApplication();
85                 if (app)
86                         return app->activeStudy();
87                 else
88                         return NULL;
89         }
90
91
92         _PTR(Study) GetActiveStudyDocument()
93         {
94                 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(GetActiveStudy());
95                 if (aStudy)
96                         return aStudy->studyDS();
97                 else
98                         return _PTR(Study)();
99         }
100
101
102         SALOME_Actor* findActorByEntry( SVTK_ViewWindow *theVtkViewWindow, const char* theEntry)
103         {
104                 SALOME_Actor *foundActor = NULL;
105                 vtkActor     *aVTKActor  = NULL;
106                 Handle(SALOME_InteractiveObject) anIO;
107
108                 vtkRenderer *aRenderer = theVtkViewWindow->getRenderer();
109                 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
110                 vtkActorCollection *aCollection = aCopy.GetActors();
111                 aCollection->InitTraversal();
112                 while( aVTKActor = aCollection->GetNextActor() ){
113                         foundActor = dynamic_cast<SALOME_Actor*>( aVTKActor );
114                         if ( foundActor && foundActor->hasIO() ){
115                                 anIO = foundActor->getIO();
116                                 if( anIO->hasEntry() && strcmp(anIO->getEntry(), theEntry) == 0 )
117                                         return foundActor;
118                         }
119                 }
120
121                 return NULL; // no actor found
122         }
123
124
125         int GetNameOfSelectedElements( SVTK_ViewWindow *theWindow,
126                         const Handle(SALOME_InteractiveObject)& theIO,
127                         QString& theName )
128         {
129                 SVTK_Selector* theSelector = theWindow->GetSelector();
130
131                 theName = "";
132
133                 TColStd_IndexedMapOfInteger aMapIndex;
134                 theSelector->GetIndex(theIO,aMapIndex);
135
136                 typedef std::set<int> TIdContainer;
137
138                 std::set<int> anIdContainer;
139
140                 for( int i = 1; i <= aMapIndex.Extent(); i++)
141                         anIdContainer.insert(aMapIndex(i));
142
143                 std::set<int>::const_iterator anIter = anIdContainer.begin();
144
145                 for( ; anIter != anIdContainer.end(); anIter++)
146                         theName += QString(" %1").arg(*anIter);
147
148                 return aMapIndex.Extent();
149         }
150
151         string shape2string( const TopoDS_Shape& aShape )
152         {
153                 ostringstream streamShape;
154                 BRepTools::Write(aShape, streamShape);
155
156                 return streamShape.str();
157         }
158
159         void getEntityOwners( const Handle(AIS_InteractiveObject)& theObj,
160                         const Handle(AIS_InteractiveContext)& theIC,
161                         SelectMgr_IndexedMapOfOwner& theMap )
162         {
163                 if ( theObj.IsNull() || theIC.IsNull() )
164                         return;
165
166                 TColStd_ListOfInteger modes;
167                 theIC->ActivatedModes( theObj, modes );
168
169                 TColStd_ListIteratorOfListOfInteger itr( modes );
170                 for (; itr.More(); itr.Next() ) {
171                         int m = itr.Value();
172                         if ( !theObj->HasSelection( m ) )
173                                 continue;
174
175                         Handle(SelectMgr_Selection) sel = theObj->Selection( m );
176
177                         for ( sel->Init(); sel->More(); sel->Next() ) {
178                                 Handle(SelectBasics_SensitiveEntity) entity = sel->Sensitive();
179                                 if ( entity.IsNull() )
180                                         continue;
181
182                                 Handle(SelectMgr_EntityOwner) owner =
183                                                 Handle(SelectMgr_EntityOwner)::DownCast(entity->OwnerId());
184                                 if ( !owner.IsNull() )
185                                         theMap.Add( owner );
186                         }
187                 }
188         }
189
190         void indicesToOwners( const TColStd_IndexedMapOfInteger& aIndexMap,
191                         const TopoDS_Shape& aMainShape,
192                         const SelectMgr_IndexedMapOfOwner& anAllMap,
193                         SelectMgr_IndexedMapOfOwner& aToHiliteMap )
194         {
195                 TopTools_IndexedMapOfShape aMapOfShapes;
196                 TopExp::MapShapes(aMainShape, aMapOfShapes);
197
198                 for  ( Standard_Integer i = 1, n = anAllMap.Extent(); i <= n; i++ )
199                 {
200                         Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(anAllMap( i ));
201                         if ( anOwner.IsNull() || !anOwner->HasShape() )
202                                 continue;
203
204                         const TopoDS_Shape& aSubShape = anOwner->Shape();
205                         Standard_Integer aSubShapeId = aMapOfShapes.FindIndex( aSubShape );
206                         if ( !aSubShapeId || !aIndexMap.Contains( aSubShapeId ) )
207                                 continue;
208
209                         if ( !aToHiliteMap.Contains( anOwner ) )
210                                 aToHiliteMap.Add( anOwner );
211                 }
212         }
213
214         TopoDS_Shape getSubShape(const TopoDS_Shape& theShape, const int theIndex)
215         {
216                 TopoDS_Shape theSubShape;
217
218                 if (theShape.IsNull() || theIndex < 1)
219                         return theSubShape;
220
221                 TopTools_IndexedMapOfShape anIndices;
222                 TopExp::MapShapes(theShape, anIndices);
223                 if (theIndex > anIndices.Extent())
224                         return theSubShape;
225                 theSubShape = anIndices.FindKey(theIndex);
226
227                 return theSubShape;
228         }
229
230         int getSubId(const TopoDS_Shape& theShape, const TopoDS_Shape& theSubShape)
231         {
232             if (theShape.IsNull() || theSubShape.IsNull())
233                 return -1;
234
235             TopTools_IndexedMapOfShape anIndices;
236             TopExp::MapShapes(theShape, anIndices);
237
238             return anIndices.FindIndex(theSubShape);
239         }
240
241         Standard_Boolean getExtremaSolution(const gp_Pnt&       theInitPnt,
242                                                                                 const TopoDS_Shape& theRefShape,
243                                                                                 gp_Pnt& thePnt)
244         {
245           BRepBuilderAPI_MakeVertex mkVertex (theInitPnt);
246           TopoDS_Vertex anInitV = TopoDS::Vertex(mkVertex.Shape());
247
248           BRepExtrema_DistShapeShape anExt (anInitV, theRefShape);
249           if ( !anExt.IsDone() || anExt.NbSolution() < 1 )
250                 return Standard_False;
251           thePnt = anExt.PointOnShape2(1);
252           Standard_Real aMinDist2 = theInitPnt.SquareDistance( thePnt );
253           for ( Standard_Integer j = 2, jn = anExt.NbSolution(); j <= jn; j++ )
254           {
255                 gp_Pnt aPnt = anExt.PointOnShape2(j);
256                 Standard_Real aDist2 = theInitPnt.SquareDistance( aPnt );
257                 if ( aDist2 > aMinDist2)
258                   continue;
259                 aMinDist2 = aDist2;
260                 thePnt = aPnt;
261           }
262           return Standard_True;
263         }
264
265         TopoDS_Vertex makePoint(const double x, const double y, const double z)
266         {
267                 gp_Pnt thePoint(x, y, z);
268                 return BRepBuilderAPI_MakeVertex(thePoint);
269         }
270
271         TopoDS_Vertex makePointWithReference(const TopoDS_Shape& point, const double dx,
272                                                                                                                          const double dy,
273                                                                                                                          const double dz)
274         {
275             TopoDS_Vertex res;
276                 gp_Pnt thePoint;
277
278                 if (point.ShapeType() != TopAbs_VERTEX) {
279                         Standard_TypeMismatch::Raise("Aborted: referenced shape is not a vertex");
280                         return res;
281                 }
282                 gp_Pnt refPoint = BRep_Tool::Pnt(TopoDS::Vertex(point));
283                 thePoint = gp_Pnt(refPoint.X() + dx, refPoint.Y() + dy, refPoint.Z() + dz);
284
285                 return BRepBuilderAPI_MakeVertex(thePoint);
286         }
287
288         TopoDS_Vertex makePointOnCurve(const TopoDS_Shape& edge, const double param)
289         {
290             TopoDS_Vertex res;
291                 gp_Pnt thePoint;
292
293                 if (edge.ShapeType() != TopAbs_EDGE) {
294                         Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
295                         return res;
296                 }
297                 Standard_Real aFP, aLP, aP;
298                 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(edge), aFP, aLP);
299                 aP = aFP + (aLP - aFP) * param;
300                 thePoint = aCurve->Value(aP);
301
302                 return BRepBuilderAPI_MakeVertex(thePoint);
303         }
304
305         TopoDS_Vertex makePointOnCurveByLength(const TopoDS_Shape& edge, const TopoDS_Shape& point, const double length)
306         {
307             TopoDS_Vertex res;
308                 gp_Pnt thePoint;
309
310                 // RefCurve
311                 if (edge.ShapeType() != TopAbs_EDGE)
312                 {
313                         Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
314                         return res;
315                 }
316                 TopoDS_Edge aRefEdge = TopoDS::Edge(edge);
317                 TopoDS_Vertex V1, V2;
318                 TopExp::Vertices(aRefEdge, V1, V2, Standard_True);
319
320                 // RefPoint
321                 TopoDS_Vertex aRefVertex;
322                 if (point.IsNull())
323                         aRefVertex = V1;
324                 else
325                 {
326                         if (point.ShapeType() != TopAbs_VERTEX)
327                         {
328                                 Standard_TypeMismatch::Raise("Aborted: shape is not a vertex");
329                                 return res;
330                         }
331                         aRefVertex = TopoDS::Vertex(point);
332                 }
333                 gp_Pnt aRefPnt = BRep_Tool::Pnt(aRefVertex);
334
335                 // Check orientation
336                 Standard_Real UFirst, ULast;
337                 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(aRefEdge, UFirst, ULast);
338                 Handle(Geom_Curve) ReOrientedCurve = EdgeCurve;
339
340                 Standard_Real dU = ULast - UFirst;
341                 Standard_Real par1 = UFirst + 0.1 * dU;
342                 Standard_Real par2 = ULast  - 0.1 * dU;
343
344                 gp_Pnt P1 = EdgeCurve->Value(par1);
345                 gp_Pnt P2 = EdgeCurve->Value(par2);
346
347                 if (aRefPnt.SquareDistance(P2) < aRefPnt.SquareDistance(P1)) {
348                         ReOrientedCurve = EdgeCurve->Reversed();
349                         UFirst = EdgeCurve->ReversedParameter(ULast);
350                 }
351
352                 // Get the point by length
353                 GeomAdaptor_Curve AdapCurve = GeomAdaptor_Curve(ReOrientedCurve);
354                 GCPnts_AbscissaPoint anAbsPnt (AdapCurve, length, UFirst);
355                 Standard_Real aParam = anAbsPnt.Parameter();
356                 thePoint = AdapCurve.Value(aParam);
357
358                 return BRepBuilderAPI_MakeVertex(thePoint);
359         }
360
361         TopoDS_Vertex makePointOnCurveByCoord(const TopoDS_Shape& edge, const double x, const double y, const double z)
362         {
363             TopoDS_Vertex res;
364                 gp_Pnt thePoint;
365
366                 if (edge.ShapeType() != TopAbs_EDGE) {
367                         Standard_TypeMismatch::Raise("Aborted: curve shape is not an edge");
368                         return res;
369                 }
370                 gp_Pnt anInitPnt (x, y, z);
371                 if (!getExtremaSolution(anInitPnt, edge, thePoint)) {
372                         Standard_ConstructionError::Raise
373                         ("Point On Surface creation aborted : cannot project point");
374                         return res;
375                 }
376
377                 return BRepBuilderAPI_MakeVertex(thePoint);
378         }
379
380         TopoDS_Vertex makePointOnLinesIntersection(const TopoDS_Shape& line1, const TopoDS_Shape& line2)
381         {
382             TopoDS_Vertex res;
383                 gp_Pnt thePoint;
384
385                 if ( (line1.ShapeType() != TopAbs_EDGE && line1.ShapeType() != TopAbs_WIRE)
386                                 || (line2.ShapeType() != TopAbs_EDGE && line2.ShapeType() != TopAbs_WIRE) ) {
387                         Standard_TypeMismatch::Raise("Aborted: Line shape is not an edge or wire");
388                         return res;
389                 }
390
391                 if (line1.IsSame(line2))
392                 {
393                         Standard_ConstructionError::Raise("The lines to make intersection must be different");
394                         return res;
395                 }
396
397                 TopoDS_Compound aCompound;
398                 bool retCompound = false;
399
400                 //Calculate Lines Intersection Point
401                 BRepExtrema_DistShapeShape dst (line1, line2);
402                 if (dst.IsDone()) {
403                         gp_Pnt P1, P2;
404                         BRep_Builder B;
405                         B.MakeCompound( aCompound );
406                         for (int i = 1, nbSols = dst.NbSolution(); i <= nbSols; i++) {
407                                 P1 = dst.PointOnShape1(i);
408                                 P2 = dst.PointOnShape2(i);
409                                 Standard_Real Dist = P1.Distance(P2);
410                                 if ( Dist <= Precision::Confusion() && dst.NbSolution() > 1) {
411                                         BRepBuilderAPI_MakeVertex mkVertex (P1);
412                                         B.Add(aCompound, mkVertex.Shape());
413                                         retCompound = true;
414                                 } else if ( Dist <= Precision::Confusion() ) {
415                                         thePoint = P1;
416                                 } else {
417                                         Standard_TypeMismatch::Raise ("Shapes have not an Intersection Point");
418                                 }
419                         }
420                 }
421                 //    TopoDS_Shape aShape;
422                 if ( retCompound ) {
423                         Standard_TypeMismatch::Raise
424                         ("Aborted: Intersection is a compound of vertices (Not supported)");
425                         //aShape = aCompound;
426                         return res;
427                 }/* else {
428                         BRepBuilderAPI_MakeVertex mkVertex (thePoint);
429                         aShape = mkVertex.Shape();
430                 }
431                 return aShape;*/
432
433                 return BRepBuilderAPI_MakeVertex(thePoint);
434         }
435
436         TopoDS_Vertex makePointOnSurface(const TopoDS_Shape& face, const double param_u, const double param_v)
437         {
438             TopoDS_Vertex res;
439                 gp_Pnt thePoint;
440
441                 if (face.ShapeType() != TopAbs_FACE) {
442                         Standard_TypeMismatch::Raise("Aborted: surface shape is not a face");
443                         return res;
444                 }
445
446                 TopoDS_Face F = TopoDS::Face(face);
447                 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
448                 Standard_Real U1,U2,V1,V2;
449                 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
450                 Standard_Real U = U1 + (U2-U1) * param_u;
451                 Standard_Real V = V1 + (V2-V1) * param_v;
452                 thePoint = aSurf->Value(U,V);
453
454                 return BRepBuilderAPI_MakeVertex(thePoint);
455         }
456
457         TopoDS_Vertex makePointOnSurfaceByCoord(const TopoDS_Shape& face, const double x, const double y, const double z)
458         {
459             TopoDS_Vertex res;
460                 gp_Pnt thePoint;
461
462                 if (face.ShapeType() != TopAbs_FACE) {
463                         Standard_TypeMismatch::Raise
464                         ("Point On Surface creation aborted : surface shape is not a face");
465                         return res;
466                 }
467                 gp_Pnt anInitPnt (x, y, z);
468                 if (!getExtremaSolution(anInitPnt, face, thePoint)) {
469                         Standard_ConstructionError::Raise
470                         ("Point On Surface creation aborted : cannot project point");
471                 }
472
473                 return BRepBuilderAPI_MakeVertex(thePoint);
474         }
475
476 }
477
478 }