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