Salome HOME
Merge from OCC_development_generic_2006
[modules/geom.git] / src / OBJECT / GEOM_AssemblyBuilder.cxx
1 //  GEOM OBJECT : interactive object for Geometry entities visualization
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : GEOM_AssemblyBuilder.cxx
25 //  Author : Christophe ATTANASIO
26 //  Module : GEOM
27 //  $Header$
28
29 /*!
30   \class GEOM_AssemblyBuilder GEOM_AssemblyBuilder.h
31   \brief ....
32 */
33
34 #include "GEOM_AssemblyBuilder.h"
35 #include "GEOM_Actor.h"
36
37 #include <vtkProperty.h>
38
39 // Open CASCADE Includes
40 #include <TopExp_Explorer.hxx>
41 #include <Bnd_Box.hxx>
42 #include <BRepMesh_IncrementalMesh.hxx>
43 #include <Poly_Triangulation.hxx>
44 #include <BRepBndLib.hxx>
45 #include <BRep_Tool.hxx>
46 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
47 #include <TopExp.hxx>
48 #include <TopTools_ListOfShape.hxx>
49 #include <TopoDS_Iterator.hxx>
50
51 #include "utilities.h"
52
53 using namespace std;
54 // SALOME
55
56 #define MAX2(X, Y)      (  Abs(X) > Abs(Y)? Abs(X) : Abs(Y) )
57 #define MAX3(X, Y, Z)   ( MAX2 ( MAX2(X,Y) , Z) )
58
59
60
61
62
63 void GEOM_AssemblyBuilder::InitProperties(vtkProperty* IsoProp,
64                                           vtkProperty* FaceProp,
65                                           vtkProperty* EdgeFProp,
66                                           vtkProperty* EdgeSProp,
67                                           vtkProperty* EdgeIProp,
68                                           vtkProperty* VertexProp,
69                                           vtkProperty* IsoPVProp,
70                                           vtkProperty* EdgePVProp,
71                                           vtkProperty* VertexPVProp)
72 {
73   // Shading like default OCC material
74   FaceProp->SetRepresentationToSurface();
75   FaceProp->SetInterpolationToGouraud();
76   FaceProp->SetAmbient(1.0);
77   FaceProp->SetDiffuse(1.0);
78   FaceProp->SetSpecular(0.4);
79   FaceProp->SetAmbientColor(0.329412, 0.223529, 0.027451);
80   FaceProp->SetDiffuseColor(0.780392, 0.568627, 0.113725);
81   FaceProp->SetSpecularColor(0.992157, 0.941176, 0.807843);
82
83   // Wireframe for iso
84   IsoProp->SetRepresentationToWireframe();
85   IsoProp->SetAmbientColor(0.5, 0.5, 0.5);
86   IsoProp->SetDiffuseColor(0.5, 0.5, 0.5);
87   IsoProp->SetSpecularColor(0.5, 0.5, 0.5);
88
89   // Wireframe for iso
90   IsoPVProp->SetRepresentationToWireframe();
91   IsoPVProp->SetAmbientColor(0, 1, 1);
92   IsoPVProp->SetDiffuseColor(0, 1, 1);
93   IsoPVProp->SetSpecularColor(0, 1, 1);
94
95   // Wireframe for shared edge 
96   EdgeSProp->SetRepresentationToWireframe();
97   EdgeSProp->SetAmbientColor(1, 1, 0);
98   EdgeSProp->SetDiffuseColor(1, 1, 0);
99   EdgeSProp->SetSpecularColor(1, 1, 0);
100
101   // Wireframe for free edge 
102   EdgeFProp->SetRepresentationToWireframe();
103   EdgeFProp->SetAmbientColor(0, 1, 0);
104   EdgeFProp->SetDiffuseColor(0, 1, 0);
105   EdgeFProp->SetSpecularColor(0, 1, 0);
106
107   // Wireframe for isolated edge 
108   EdgeIProp->SetRepresentationToWireframe();
109   EdgeIProp->SetAmbientColor(1, 0, 0);
110   EdgeIProp->SetDiffuseColor(1, 0, 0);
111   EdgeIProp->SetSpecularColor(1, 0, 0);
112
113   // Wireframe for Preview edge 
114   EdgePVProp->SetRepresentationToWireframe();
115   EdgePVProp->SetAmbientColor(1, 1, 0);
116   EdgePVProp->SetDiffuseColor(1, 1, 0);
117   EdgePVProp->SetSpecularColor(1, 1, 0);
118
119   // Wireframe for vertex 
120   VertexProp->SetRepresentationToWireframe();
121   VertexProp->SetAmbientColor(1, 1, 0);
122   VertexProp->SetDiffuseColor(1, 1, 0);
123   VertexProp->SetSpecularColor(1, 1, 0);
124
125   // Wireframe for vertex 
126   VertexPVProp->SetRepresentationToWireframe();
127   VertexPVProp->SetAmbientColor(0, 1, 1);
128   VertexPVProp->SetDiffuseColor(0, 1, 1);
129   VertexPVProp->SetSpecularColor(0, 1, 1);
130 }
131
132
133 void GEOM_AssemblyBuilder::MeshShape(const TopoDS_Shape myShape,
134                                          Standard_Real deflection,
135                                          Standard_Boolean forced)
136 {
137   // Mesh the shape if necessary
138   Standard_Boolean alreadymesh = Standard_True;
139   TopExp_Explorer ex;
140   TopLoc_Location aLoc;
141
142   for (ex.Init(myShape, TopAbs_FACE); ex.More(); ex.Next()) {
143     const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
144     Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
145     if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
146   }
147
148   if(!alreadymesh || forced) {
149     if(deflection<=0) {
150       // Compute default deflection
151       Bnd_Box B;
152       BRepBndLib::Add(myShape, B);
153       Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
154       B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
155       deflection = MAX3( aXmax-aXmin , aYmax-aYmin , aZmax-aZmin) * 0.001 *4;
156     }
157     BRepMesh_IncrementalMesh MESH(myShape,deflection);
158   }
159 }
160
161
162
163 vtkActorCollection* GEOM_AssemblyBuilder::BuildActors(const TopoDS_Shape& myShape,
164                                                           Standard_Real deflection,
165                                                           Standard_Integer mode,
166                                                           Standard_Boolean forced) {
167
168   vtkActorCollection* AISActors = vtkActorCollection::New();
169
170   if(myShape.ShapeType() == TopAbs_COMPOUND) {
171     TopoDS_Iterator anItr(myShape);
172     for(; anItr.More(); anItr.Next()) {
173       vtkActorCollection* theActors = GEOM_AssemblyBuilder::BuildActors(anItr.Value(), deflection, mode, forced);
174       theActors->InitTraversal();
175       vtkActor* anActor = (vtkActor*)theActors->GetNextActor();
176       while(!(anActor==NULL)) {
177         AISActors->AddItem(anActor);
178         anActor = (vtkActor*)theActors->GetNextActor();
179       }
180     }
181   }
182   // Create graphics properties
183
184   vtkProperty* IsoProp = vtkProperty::New();
185   vtkProperty* FaceProp = vtkProperty::New();
186   vtkProperty* EdgeFProp = vtkProperty::New();
187   vtkProperty* EdgeSProp = vtkProperty::New();
188   vtkProperty* EdgeIProp = vtkProperty::New();
189   vtkProperty* VertexProp = vtkProperty::New();
190
191   vtkProperty* IsoPVProp = vtkProperty::New();
192   vtkProperty* EdgePVProp = vtkProperty::New();
193   vtkProperty* VertexPVProp = vtkProperty::New();
194
195   InitProperties(IsoProp,FaceProp,EdgeFProp,EdgeSProp,EdgeIProp,VertexProp,IsoPVProp,EdgePVProp,VertexPVProp);
196
197   MeshShape(myShape,deflection,forced);
198
199   if ( myShape.ShapeType() <= 4 && myShape.ShapeType() != TopAbs_COMPOUND) {
200     
201     // FACE Actor
202     // look if edges are free or shared 
203     TopTools_IndexedDataMapOfShapeListOfShape edgemap;
204     TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,edgemap);
205     
206     TopExp_Explorer ex;
207     
208     for (ex.Init(myShape, TopAbs_FACE); ex.More(); ex.Next()) {
209       
210       GEOM_Actor* FaceActor = GEOM_Actor::New();
211       FaceActor->SetShadingProperty(FaceProp);
212       FaceActor->SetWireframeProperty(IsoProp);
213
214       FaceActor->SetPreviewProperty(IsoPVProp);
215       
216       FaceActor->setInputShape(ex.Current(),deflection,mode);
217       
218       AISActors->AddItem(FaceActor);
219       
220       TopExp_Explorer ex2;
221       for (ex2.Init(ex.Current(), TopAbs_EDGE); ex2.More(); ex2.Next()) {
222         const TopoDS_Edge& aEdge = TopoDS::Edge(ex2.Current());
223         
224         if (BRep_Tool::Degenerated(aEdge)) {    
225           continue;
226         }
227         
228         // compute the number of faces
229         Standard_Integer nbf = edgemap.FindFromKey(ex2.Current()).Extent();
230         GEOM_Actor* EdgeActor = GEOM_Actor::New();
231         EdgeActor->SubShapeOn();
232         EdgeActor->setInputShape(ex2.Current(),deflection,mode);
233         switch (nbf) {
234           
235         case 0 : // isolated edge
236           {
237             EdgeActor->SetShadingProperty(EdgeIProp);
238             EdgeActor->SetWireframeProperty(EdgeIProp);
239           }
240           break;
241           
242         case 1 :// edge in only one face
243           {
244             EdgeActor->SetShadingProperty(EdgeFProp);
245             EdgeActor->SetWireframeProperty(EdgeFProp);
246           }
247           break;
248           
249         default :   // edge shared by at least two faces      
250           {
251             EdgeActor->SetShadingProperty(EdgeSProp);
252             EdgeActor->SetWireframeProperty(EdgeSProp);
253           }
254         }
255         EdgeActor->SetPreviewProperty(EdgePVProp);
256         AISActors->AddItem(EdgeActor);
257       }
258     }
259   } else if ( myShape.ShapeType() == TopAbs_WIRE ) { // WIRE Actor
260     TopExp_Explorer ex;
261     for (ex.Init(myShape, TopAbs_EDGE); ex.More(); ex.Next()) {
262       const TopoDS_Edge& aEdge = TopoDS::Edge(ex.Current());
263         
264       if (BRep_Tool::Degenerated(aEdge)) {    
265         continue;
266       }
267         
268       GEOM_Actor* EdgeActor = GEOM_Actor::New();
269       EdgeActor->setInputShape(ex.Current(),deflection,mode);
270       EdgeActor->SetShadingProperty(EdgeIProp);
271       EdgeActor->SetWireframeProperty(EdgeIProp);
272       EdgeActor->SetPreviewProperty(EdgePVProp);
273       
274       AISActors->AddItem(EdgeActor);
275     }
276   } else if ( myShape.ShapeType() == TopAbs_EDGE ) { // EDGE Actor
277     GEOM_Actor* EdgeActor = GEOM_Actor::New();
278     EdgeActor->setInputShape(myShape,deflection,mode);
279     EdgeActor->SetShadingProperty(EdgeIProp);
280     EdgeActor->SetWireframeProperty(EdgeIProp);
281     EdgeActor->SetPreviewProperty(EdgePVProp);
282     
283     AISActors->AddItem(EdgeActor);
284   } else if ( myShape.ShapeType() == TopAbs_VERTEX ) { // VERTEX Actor
285     GEOM_Actor* VertexActor = GEOM_Actor::New();
286     VertexActor->setInputShape(myShape,deflection,mode);
287     VertexActor->SetShadingProperty(VertexProp);
288     VertexActor->SetWireframeProperty(VertexProp);
289     VertexActor->SetPreviewProperty(VertexPVProp);
290     
291     AISActors->AddItem(VertexActor);
292   
293   } 
294   
295   return AISActors;
296
297 }
298
299
300
301 //-------------------------------------------------------------
302 // BUILD ASSEMBLY
303 //-------------------------------------------------------------
304 vtkAssembly*  GEOM_AssemblyBuilder::BuildAssembly(const TopoDS_Shape& myShape,
305                                                       Standard_Real deflection,
306                                                       Standard_Integer mode,
307                                                       Standard_Boolean forced)
308 {
309   // Create a new vtkAssembly
310
311   vtkAssembly* myVTKShape = vtkAssembly::New();
312
313
314   // Create graphics properties
315
316   vtkProperty* IsoProp = vtkProperty::New();
317   vtkProperty* FaceProp = vtkProperty::New();
318   vtkProperty* EdgeFProp = vtkProperty::New();
319   vtkProperty* EdgeSProp = vtkProperty::New();
320   vtkProperty* EdgeIProp = vtkProperty::New();
321   vtkProperty* VertexProp = vtkProperty::New();
322   vtkProperty* EdgePVProp = vtkProperty::New();
323   vtkProperty* VertexPVProp = vtkProperty::New();
324   vtkProperty* IsoPVProp = vtkProperty::New();
325
326   InitProperties(IsoProp,FaceProp,EdgeFProp,EdgeSProp,EdgeIProp,VertexProp,IsoPVProp,EdgePVProp,VertexPVProp);
327
328   MeshShape(myShape,deflection,forced);
329
330   
331   // FACE Actor
332   
333   // look if edges are free or shared 
334   TopTools_IndexedDataMapOfShapeListOfShape edgemap;
335   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,edgemap);
336   
337   TopExp_Explorer ex;
338
339   for (ex.Init(myShape, TopAbs_FACE); ex.More(); ex.Next()) {
340     //const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
341     
342     GEOM_Actor* FaceActor = GEOM_Actor::New();
343     FaceActor->SetShadingProperty(FaceProp);
344     FaceActor->SetWireframeProperty(IsoProp);
345     
346     vtkAssembly* myFaceAssembly = vtkAssembly::New();
347
348    
349     FaceActor->setInputShape(ex.Current(),deflection,mode);
350     myFaceAssembly->AddPart(FaceActor);
351     
352     TopExp_Explorer ex2;
353     for (ex2.Init(ex.Current(), TopAbs_EDGE); ex2.More(); ex2.Next()) {
354       const TopoDS_Edge& aEdge = TopoDS::Edge(ex2.Current());
355  
356       if (BRep_Tool::Degenerated(aEdge)) {    
357         continue;
358       }
359       
360     
361       // compute the number of faces
362       Standard_Integer nbf = edgemap.FindFromKey(ex2.Current()).Extent();
363       GEOM_Actor* EdgeActor = GEOM_Actor::New();
364       switch (nbf) {
365         
366       case 0 : // isolated edge
367         {
368           EdgeActor->SetShadingProperty(EdgeIProp);
369           EdgeActor->SetWireframeProperty(EdgeIProp);
370         }
371         break;
372         
373       case 1 :// edge in only one face
374         {
375           EdgeActor->SetShadingProperty(EdgeFProp);
376           EdgeActor->SetWireframeProperty(EdgeFProp);
377         }
378         break;
379         
380       default :   // edge shared by at least two faces      
381         {
382           EdgeActor->SetShadingProperty(EdgeSProp);
383           EdgeActor->SetWireframeProperty(EdgeSProp);
384         }
385       }
386   
387       EdgeActor->setInputShape(ex2.Current(),deflection,mode);
388       myFaceAssembly->AddPart(EdgeActor);
389     }
390     myVTKShape->AddPart(myFaceAssembly);
391   }
392   
393   return myVTKShape;
394  
395 }
396
397 //-------------------------------------------------------------
398 // CHANGE SPECIFIC DISPLAY MODE
399 //-------------------------------------------------------------
400 void  GEOM_AssemblyBuilder::SwitchDisplayMode(vtkAssembly* aOCCAssembly)
401 {
402 }
403
404 void  GEOM_AssemblyBuilder::SwitchDisplayMode(vtkActorCollection* aOCCAssembly)
405 {
406 }
407
408 //-------------------------------------------------------------
409 // DISPLAY/ERASE
410 //-------------------------------------------------------------
411
412 void GEOM_AssemblyBuilder::DisplayErase(vtkAssembly* mySALOMEAssembly)
413 {
414 }
415
416
417 void GEOM_AssemblyBuilder::DisplayErase(vtkActorCollection* mySALOMEActors)
418 {
419 }
420
421
422
423
424