Salome HOME
Merge from V5_1_main 14/05/2010
[modules/visu.git] / src / VISU_I / VISU_ClippingPlaneMgr.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
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.
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 "VISU_ClippingPlaneMgr.hxx"
21 #include "VISU_ColoredPrs3dHolder_i.hh"
22
23 //#include CORBA_SERVER_HEADER(SALOMEDS)
24 //#include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
25
26 #include "SALOMEDSClient_GenericAttribute.hxx"
27 #include "SALOMEDSClient_AttributeName.hxx"
28 #include "SALOMEDSClient_AttributeSequenceOfReal.hxx"
29 #include "SALOMEDSClient_AttributeInteger.hxx"
30
31
32 #include <vtkImplicitFunctionCollection.h>
33
34
35 #define CLIP_PLANES_FOLDER "Clipping Planes"
36
37 using namespace std;
38
39 //*************************************************************
40 VISU_ClippingPlaneMgr::VISU_ClippingPlaneMgr()
41 {
42   myPlanes = vtkImplicitFunctionCollection::New();
43 }
44
45 //*************************************************************
46 VISU_ClippingPlaneMgr::~VISU_ClippingPlaneMgr()
47 {
48   myPlanes->Delete();
49 }
50
51 //*************************************************************
52 void VISU_ClippingPlaneMgr::SetStudy(_PTR(Study) theStudy)
53 {
54   if (myStudy == theStudy) return;
55   myStudy = theStudy;
56   myPlanes->RemoveAllItems();
57   if (!myStudy) return;
58
59   _PTR(SObject) aFolder = GetClippingPlanesFolder(false);
60   if (aFolder) {
61     _PTR(ChildIterator) aIter = myStudy->NewChildIterator(aFolder);
62     int i;
63     for (i = 0; aIter->More(); aIter->Next(), i++) { // For each plane
64       _PTR(SObject) aSObject = aIter->Value();
65       VISU_CutPlaneFunction* aPlane = VISU_CutPlaneFunction::New();
66       aPlane->setPlaneObject(aSObject);
67       aPlane->setName(aSObject->GetName());
68       
69       _PTR(GenericAttribute) anAttr;
70       if (aSObject->FindAttribute(anAttr, "AttributeSequenceOfReal")) {
71         _PTR(AttributeSequenceOfReal) aArray(anAttr);
72         aPlane->SetOrigin(aArray->Value(1), aArray->Value(2), aArray->Value(3));
73         aPlane->SetNormal(aArray->Value(4), aArray->Value(5), aArray->Value(6));
74       }
75       if (aSObject->FindAttribute(anAttr, "AttributeInteger")) {
76         _PTR(AttributeInteger) aFlag(anAttr);
77         aPlane->setAuto(aFlag->Value() == 1);
78       } else
79         aPlane->setAuto(false);
80
81       applyPlaneToAll(aPlane);
82       myPlanes->AddItem(aPlane);
83     }
84   }
85 }
86
87
88 void VISU_ClippingPlaneMgr::applyPlaneToAll(VISU_CutPlaneFunction* thePlane)
89 {
90   _PTR(SComponent) aVisuSO = myStudy->FindComponent("VISU");
91   _PTR(ChildIterator) aChildIter = myStudy->NewChildIterator(aVisuSO);
92   for (aChildIter->InitEx(true); aChildIter->More(); aChildIter->Next()) {
93     _PTR(SObject) aSObject = aChildIter->Value();
94     CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
95     if(VISU::Base_i* aBase = dynamic_cast<VISU::Base_i*>(VISU::GetServant(anObject).in())) {
96       VISU::Prs3d_i* aPrs;
97       if(aBase->GetType() == VISU::TCOLOREDPRS3DHOLDER){
98         CORBA::Object_var anObject = aBase->_this();
99         VISU::ColoredPrs3dHolder_var aHolder = VISU::ColoredPrs3dHolder::_narrow(anObject);
100         VISU::Prs3d_var aPrs3d = aHolder->GetDevice();
101         aPrs = dynamic_cast<VISU::Prs3d_i*>(VISU::GetServant(aPrs3d).in());
102       } else {
103         aPrs = dynamic_cast<VISU::Prs3d_i*>(aBase);
104       }
105       if (aPrs) {
106         if (!ContainsPlane(aPrs, thePlane)) {
107           if (thePlane->isAuto())
108             aPrs->AddClippingPlane(thePlane);
109           else {
110             string aPrsEntry = aPrs->GetEntry();
111             if (aPrsEntry.length() == 0) {
112               VISU::ColoredPrs3d_i* aColPrs = dynamic_cast<VISU::ColoredPrs3d_i*>(aPrs);
113               if (aColPrs)
114                 aPrsEntry = aColPrs->GetHolderEntry();
115             }
116             
117             _PTR(SObject) aSObject = thePlane->getPlaneObject();
118             _PTR(ChildIterator) aRefIter = myStudy->NewChildIterator(aSObject);   
119             for (; aRefIter->More(); aRefIter->Next()) {
120               _PTR(SObject) aObj = aRefIter->Value();
121               _PTR(SObject) aRefPrsObject;
122               if (aObj->ReferencedObject(aRefPrsObject)) { // If it is referenced on current plane
123                 if (aRefPrsObject->GetID() == aPrsEntry) {
124                   aPrs->AddClippingPlane(thePlane);
125                 }
126               }
127             }
128           }
129         }
130       }
131     }
132   } 
133 }
134
135 //*************************************************************
136 long VISU_ClippingPlaneMgr::CreateClippingPlane(double X,double  Y, double Z, 
137                                                 double dX, double dY, double dZ, 
138                                                 bool isAuto, const char* name)
139 {
140   _PTR(SObject) aObjPtr = CreateClippingPlaneObject(X, Y, Z, dX, dY, dZ, isAuto, name);
141   return myPlanes->GetNumberOfItems() - 1;
142 }
143
144
145 //*************************************************************
146 _PTR(SObject) VISU_ClippingPlaneMgr::CreateClippingPlaneObject(double X,double  Y, double Z, 
147                                                                double dX, double dY, double dZ, 
148                                                                bool isAuto, const char* name)
149 {
150   _PTR(SObject) aPlaneObj;
151   if(!myStudy->GetProperties()->IsLocked()) {
152     _PTR(SObject) aFolder = GetClippingPlanesFolder(true);
153     if (aFolder) {
154       _PTR(StudyBuilder) aBuilder = myStudy->NewBuilder();
155       aPlaneObj = aBuilder->NewObject(aFolder);
156
157       // Save Name
158       _PTR(GenericAttribute) anAttr;
159       anAttr = aBuilder->FindOrCreateAttribute(aPlaneObj,"AttributeName");
160       _PTR(AttributeName) aName(anAttr);
161       aName->SetValue(name);
162
163       //Save Parameters
164       double aParams[6];
165       aParams[0] = X;
166       aParams[1] = Y;
167       aParams[2] = Z;
168       aParams[3] = dX;
169       aParams[4] = dY;
170       aParams[5] = dZ;
171
172       anAttr = aBuilder->FindOrCreateAttribute(aPlaneObj,"AttributeSequenceOfReal");
173       _PTR(AttributeSequenceOfReal) aArray(anAttr);
174       if (aArray->Length() == 6) {
175         for (int i = 0; i < 6; i++)
176           aArray->ChangeValue(i+1, aParams[i]);
177       } else {
178         for (int i = 0; i < 6; i++)
179           aArray->Add(aParams[i]);
180       }
181       // Save Bool Flag
182       anAttr = aBuilder->FindOrCreateAttribute(aPlaneObj,"AttributeInteger");
183       _PTR(AttributeInteger) aFlag(anAttr);
184       aFlag->SetValue(isAuto? 1 : 0);
185
186       vtkSmartPointer<VISU_CutPlaneFunction> aPlane = VISU_CutPlaneFunction::New();
187       aPlane->Delete(); //vtkSmartPointer specific
188       aPlane->setPlaneObject(aPlaneObj);
189       aPlane->SetOrigin(X, Y, Z);
190       aPlane->SetNormal(dX, dY, dZ);
191       aPlane->setName(name);
192       aPlane->setAuto(isAuto);
193       applyPlaneToAll(aPlane);
194       myPlanes->AddItem(aPlane.GetPointer());
195     }
196   }
197   return aPlaneObj;
198 }
199   
200
201 //*************************************************************
202 void VISU_ClippingPlaneMgr::EditClippingPlane(long id, double X,double  Y, double Z, 
203                                               double dX, double dY, double dZ, 
204                                               bool isAuto, const char* name)
205 {
206   VISU_CutPlaneFunction* aPlane = GetClippingPlane(id);
207   if (aPlane != NULL) {
208     _PTR(SObject) aSObj = aPlane->getPlaneObject();
209     aPlane->SetOrigin(X, Y, Z);
210     aPlane->SetNormal(dX, dY, dZ);
211     aPlane->setName(name);
212     aPlane->setAuto(isAuto);
213
214     if(!myStudy->GetProperties()->IsLocked()) {
215       _PTR(GenericAttribute) anAttr;
216       if (aSObj->FindAttribute(anAttr, "AttributeSequenceOfReal")) {
217         _PTR(AttributeSequenceOfReal) aArray(anAttr);
218         aArray->ChangeValue(1, X);
219         aArray->ChangeValue(2, Y);
220         aArray->ChangeValue(3, Z);
221         aArray->ChangeValue(4, dX);
222         aArray->ChangeValue(5, dY);
223         aArray->ChangeValue(6, dZ);
224       }
225       if (aSObj->FindAttribute(anAttr, "AttributeInteger")) {
226         _PTR(AttributeInteger) aFlag(anAttr);
227         aFlag->SetValue(isAuto? 1 : 0);
228       }
229       if (aSObj->FindAttribute(anAttr, "AttributeName")) {
230         _PTR(AttributeName) aName(anAttr);
231         aName->SetValue(name);
232       }
233       // Remove references on presentations if it becomes Auto plane
234       _PTR(SObject) aPlaneSObj = aPlane->getPlaneObject();
235       if (aPlane->isAuto()) {
236         _PTR(ChildIterator) aIter = myStudy->NewChildIterator(aPlaneSObj);
237         _PTR(StudyBuilder) aBuilder = myStudy->NewBuilder();
238         for (; aIter->More(); aIter->Next()) {
239           _PTR(SObject) aObj = aIter->Value();
240           aBuilder->RemoveObject(aObj);
241         }
242       } 
243     }
244   }
245 }
246
247
248
249 //*************************************************************
250   /* Returns clipping plane by its Id */
251 VISU_CutPlaneFunction* VISU_ClippingPlaneMgr::GetClippingPlane(long id)
252 {
253   if ((id < 0) || (id >= GetClippingPlanesNb()))
254     return NULL;
255   return (VISU_CutPlaneFunction*) myPlanes->GetItemAsObject(id);
256 }
257
258 //*************************************************************
259   /* Returns -1 if Plane is not exists */
260 int VISU_ClippingPlaneMgr::GetPlaneId(VISU_CutPlaneFunction* thePlane)
261 {
262   int aTag = thePlane->getPlaneObject()->Tag();
263   int aRes = -1;
264   VISU_CutPlaneFunction* aPlane;
265   for (int i = 0; i < GetClippingPlanesNb(); i++) {
266     aPlane = GetClippingPlane(i);
267     if (aPlane->getPlaneObject()->Tag() == aTag) {
268       aRes = i;
269       break;
270     }
271   }
272   return aRes;
273 }
274
275   
276 //*************************************************************
277   /* Deletes clipping plane by its Id */
278 bool VISU_ClippingPlaneMgr::DeleteClippingPlane(long id)
279 {
280   _PTR(SObject) aFolder = GetClippingPlanesFolder(false);
281   if (aFolder) {
282     VISU_CutPlaneFunction* aPlane = GetClippingPlane(id);
283     if (aPlane != NULL) {
284       _PTR(SComponent) aVisuSO = myStudy->FindComponent("VISU");
285       _PTR(ChildIterator) aChildIter = myStudy->NewChildIterator(aVisuSO);
286       for (aChildIter->InitEx(true); aChildIter->More(); aChildIter->Next()) {
287         _PTR(SObject) aSObject = aChildIter->Value();
288         CORBA::Object_var anObject = VISU::ClientSObjectToObject(aSObject);
289         if(VISU::Base_i* aBase = dynamic_cast<VISU::Base_i*>(VISU::GetServant(anObject).in())) {
290           VISU::Prs3d_i* aPrs;
291           if(aBase->GetType() == VISU::TCOLOREDPRS3DHOLDER){
292             CORBA::Object_var anObject = aBase->_this();
293             VISU::ColoredPrs3dHolder_var aHolder = VISU::ColoredPrs3dHolder::_narrow(anObject);
294             VISU::Prs3d_var aPrs3d = aHolder->GetDevice();
295             aPrs = dynamic_cast<VISU::Prs3d_i*>(VISU::GetServant(aPrs3d).in());
296           } else
297             aPrs = dynamic_cast<VISU::Prs3d_i*>(aBase);
298
299           if (aPrs) {
300             if (ContainsPlane(aPrs, aPlane)) {
301               short aTag1 = aPlane->getPlaneObject()->Tag();
302               for (int j = aPrs->GetNumberOfClippingPlanes()-1; j > -1; j--) {
303                 VISU_CutPlaneFunction* aPln = dynamic_cast<VISU_CutPlaneFunction*>
304                   (aPrs->GetClippingPlane(j));
305                 if (aPln) {
306                   short aTag2 = aPln->getPlaneObject()->Tag();
307                   if (aTag1 == aTag2) {
308                     aPrs->RemoveClippingPlane(j);
309                     break;
310                   }
311                 }
312               }
313             }
314           }
315         }
316       }   
317       _PTR(SObject) aSObj = aPlane->getPlaneObject();
318       if (aSObj) {
319         _PTR(StudyBuilder) aBuilder = myStudy->NewBuilder();
320         aBuilder->RemoveObject(aSObj);
321       }
322       myPlanes->RemoveItem(id);
323       return true;
324     }
325   }
326   return false;
327 }
328
329 //*************************************************************
330 bool VISU_ClippingPlaneMgr::ContainsPlane(VISU::Prs3d_ptr thePrs, VISU_CutPlaneFunction* thePlane)
331 {
332   VISU::Prs3d_i* aPrs = dynamic_cast<VISU::Prs3d_i*>(VISU::GetServant(thePrs).in());
333   return ContainsPlane(aPrs, thePlane);
334 }
335
336 //*************************************************************
337 bool VISU_ClippingPlaneMgr::ContainsPlane(VISU::Prs3d_i* thePrs, VISU_CutPlaneFunction* thePlane)
338 {
339   VISU::Prs3d_i* aPrs = thePrs;
340   if (thePrs->GetType() == VISU::TCOLOREDPRS3DHOLDER) {
341     VISU::ColoredPrs3dHolder_i* aHolder = dynamic_cast<VISU::ColoredPrs3dHolder_i*>(thePrs);
342     if (!aHolder) return false;
343     aPrs = aHolder->GetPrs3dDevice();
344   }
345   string aEntry = thePlane->getPlaneObject()->GetID();
346   for (int i = 0; i < thePrs->GetNumberOfClippingPlanes(); i++) {
347     VISU_CutPlaneFunction* aPlane = dynamic_cast<VISU_CutPlaneFunction*>(thePrs->GetClippingPlane(i));
348     if (aPlane) {
349       if (aPlane->getPlaneObject()->GetID() == aEntry) {
350         return true;
351       }
352     }
353   }
354   return false;
355 }
356
357   
358 //*************************************************************
359   /* Applyes a clipping plane with Id to presentation thePrs */
360 bool VISU_ClippingPlaneMgr::ApplyClippingPlane(VISU::Prs3d_i* thePrs, long id) 
361 {
362   //VISU::Prs3d_i* aPrs = dynamic_cast<VISU::Prs3d_i*>(VISU::GetServant(thePrs).in());
363   if (!thePrs) return false;
364
365   VISU_CutPlaneFunction* aPlane = GetClippingPlane(id);
366   if (!aPlane) return false;
367   if (!ContainsPlane(thePrs, aPlane)) {
368     thePrs->AddClippingPlane(aPlane);
369     if (!aPlane->isAuto()) {
370       string aEntry = thePrs->GetEntry();
371       if (aEntry.length() == 0) {
372         VISU::ColoredPrs3d_i* aColPrs = dynamic_cast<VISU::ColoredPrs3d_i*>(thePrs);
373         if (aColPrs)
374           aEntry = aColPrs->GetHolderEntry();
375       }
376       if(!myStudy->GetProperties()->IsLocked()) {
377         _PTR(StudyBuilder) aBuilder = myStudy->NewBuilder();
378         _PTR(SObject) aPrsSObj = myStudy->FindObjectID(aEntry);
379         _PTR(SObject) aSObject = aPlane->getPlaneObject();
380         _PTR(SObject) aNewObj = aBuilder->NewObject(aSObject);
381         aBuilder->Addreference(aNewObj, aPrsSObj);
382       }
383     }
384     return true;
385   }
386   return false;
387 }
388
389 //*************************************************************
390 bool VISU_ClippingPlaneMgr::DetachClippingPlane(VISU::Prs3d_i* thePrs, long id) 
391 {
392   VISU_CutPlaneFunction* aPlane = GetClippingPlane(id);
393   //VISU::Prs3d_i* aPrs = dynamic_cast<VISU::Prs3d_i*>(VISU::GetServant(thePrs).in());
394   if (aPlane && thePrs) {
395     if (ContainsPlane(thePrs, aPlane)) {
396       bool isRemoved = false;
397       short aTag1 = aPlane->getPlaneObject()->Tag();
398       for (int j = thePrs->GetNumberOfClippingPlanes()-1; j > -1; j--) {
399         VISU_CutPlaneFunction* aPln = dynamic_cast<VISU_CutPlaneFunction*>
400           (thePrs->GetClippingPlane(j));
401         if (aPln) {
402           short aTag2 = aPln->getPlaneObject()->Tag();
403           if (aTag1 == aTag2) {
404             thePrs->RemoveClippingPlane(j);
405             isRemoved = true;
406             break;
407           }
408         }
409       }
410       if(!myStudy->GetProperties()->IsLocked()) {
411         _PTR(SObject) aSObject = aPlane->getPlaneObject();
412         _PTR(StudyBuilder) aBuilder = myStudy->NewBuilder();
413
414         string aEntry = thePrs->GetEntry();
415         if (aEntry.length() == 0) {
416           VISU::ColoredPrs3d_i* aColPrs = dynamic_cast<VISU::ColoredPrs3d_i*>(thePrs);
417           if (aColPrs)
418             aEntry = aColPrs->GetHolderEntry();
419         }
420         _PTR(ChildIterator) aIter = myStudy->NewChildIterator(aSObject);
421         for (; aIter->More(); aIter->Next()) {
422           _PTR(SObject) aRefObj = aIter->Value();
423           if(aRefObj) {
424             _PTR(SObject) aRefPrsObject;
425             if (aRefObj->ReferencedObject(aRefPrsObject)) {
426               if (aRefPrsObject->GetID() == aEntry) {
427                 aBuilder->RemoveObject(aRefObj);
428                 break;
429               }
430             }
431           }
432         }
433       }
434       return isRemoved;
435     }
436   }
437   return false;
438 }
439
440   
441 //*************************************************************
442   /* Get number of clipping planes */
443 long VISU_ClippingPlaneMgr::GetClippingPlanesNb() 
444 {
445   return myPlanes->GetNumberOfItems();
446 }
447
448
449 //*************************************************************
450 _PTR(SObject) VISU_ClippingPlaneMgr::GetClippingPlanesFolder(bool toCreate)
451 {
452   _PTR(SObject) aFolder;
453   _PTR(SComponent) aVisuSO = myStudy->FindComponent("VISU");
454   if (!aVisuSO) return aFolder;
455
456   aFolder = myStudy->FindObject(CLIP_PLANES_FOLDER);
457   if (!aFolder && toCreate) {
458     _PTR(StudyBuilder) aBuilder = myStudy->NewBuilder();
459     aFolder = aBuilder->NewObject(aVisuSO);
460     
461     _PTR(GenericAttribute) anAttr;
462     anAttr = aBuilder->FindOrCreateAttribute(aFolder,"AttributeName");
463     _PTR(AttributeName) aName(anAttr);
464     aName->SetValue(CLIP_PLANES_FOLDER);
465   }
466   return aFolder;
467 }
468
469
470
471
472 //****************************************************************
473 //****************************************************************
474 //****************************************************************
475 VISU_CutPlaneFunction* VISU_CutPlaneFunction::New()
476 {
477   return new VISU_CutPlaneFunction();
478 }
479
480 void VISU_CutPlaneFunction::setActive(bool theActive) 
481
482   myIsActive = theActive; 
483   Modified();
484 }
485
486 double VISU_CutPlaneFunction::EvaluateFunction(double x[3])
487 {
488   if (myIsActive)
489     return vtkPlane::EvaluateFunction(x);
490   else 
491     return -1;
492 }
493
494 double VISU_CutPlaneFunction::EvaluateFunction(double x, double y, double z)
495 {
496   if (myIsActive)
497     return vtkPlane::EvaluateFunction(x,y,z);
498   else 
499     return -1;
500 }
501   
502 VISU_CutPlaneFunction::VISU_CutPlaneFunction():
503   myIsActive(true)
504 {
505 }
506
507 VISU_CutPlaneFunction::~VISU_CutPlaneFunction()
508 {
509 }
510