Salome HOME
Compilation by CMake.
[modules/hydro.git] / src / HYDROOperations / HYDROOperations_Factory.cxx
1 #include<HYDROOperations_Factory.h>
2
3 #include<HYDROData_Document.h>
4 #include<HYDROData_Iterator.h>
5
6 #include<ImageComposer_ColorMaskOperator.h>
7 #include<ImageComposer_CropOperator.h>
8 #include<ImageComposer_CutOperator.h>
9 #include<ImageComposer_FuseOperator.h>
10 #include<ImageComposer_Image.h>
11
12 #include <typeinfo>
13
14 // global instance
15 HYDROOperations_Factory* FACTORY = 0;
16
17 HYDROOperations_Factory* HYDROOperations_Factory::Factory()
18 {
19   if (!FACTORY) {
20     FACTORY = new HYDROOperations_Factory;
21     // default operations
22     REGISTER_HYDRO_OPERATION(ImageComposer_ColorMaskOperator)
23     REGISTER_HYDRO_OPERATION(ImageComposer_CropOperator)
24     REGISTER_HYDRO_OPERATION(ImageComposer_CutOperator)
25     REGISTER_HYDRO_OPERATION(ImageComposer_FuseOperator)
26   }
27   return FACTORY;
28 }
29
30 ImageComposer_Operator* HYDROOperations_Factory::Operator(const QString theName) const
31 {
32   if (myOps.contains(theName)) {
33     return myOps[theName];
34   }
35   return NULL;
36 }
37
38 void HYDROOperations_Factory::Register(
39   ImageComposer_Operator* theOperator)
40 {
41   FACTORY->myOps[QString(typeid(*theOperator).name())] = theOperator;
42 }
43
44 HYDROOperations_Factory::HYDROOperations_Factory()
45 {
46 }
47
48 ImageComposer_Operator* HYDROOperations_Factory::Operator(
49   Handle(HYDROData_Image) theImage) const
50 {
51   // retreive operator instance by name
52   ImageComposer_Operator* anOp = Operator(theImage->OperatorName());
53   if (!anOp)
54     return anOp;
55   // fill arguments of the operator from theImage
56   theImage->Args();
57   anOp->setBinArgs(theImage->Args());
58   return anOp;
59 }
60
61 Handle(HYDROData_Image) HYDROOperations_Factory::CreateImage(
62   Handle(HYDROData_Document) theDoc, const ImageComposer_Operator* theOperator)
63 {
64   // create an object
65   Handle(HYDROData_Image) anImage = 
66     Handle(HYDROData_Image)::DownCast(theDoc->CreateObject(KIND_IMAGE));
67   // get data from operation
68   if (theOperator) {
69     anImage->SetOperatorName(QString(typeid(*theOperator).name()));
70     anImage->SetArgs(theOperator->getBinArgs());
71   }
72   return anImage;
73 }
74
75 void HYDROOperations_Factory::UpdateImage(
76   Handle_HYDROData_Document theDoc, Handle(HYDROData_Image) theImage)
77 {
78   // fill by arguments and process the operation
79   ImageComposer_Operator* anOp = Operator(theImage);
80   if (anOp) { // update image only if there is an operation
81     ImageComposer_Image anImage1; // first referenced image
82     if (theImage->NbReferences()) {
83       Handle(HYDROData_Image) anImage = theImage->Reference(0);
84       anImage1 = anImage->Image();
85       anImage1.setTransform(anImage->Trsf());
86     }
87     ImageComposer_Image anImage2; // second referenced image
88     if (theImage->NbReferences() > 1) {
89       Handle(HYDROData_Image) anImage = theImage->Reference(1);
90       anImage2 = anImage->Image();
91       anImage2.setTransform(anImage->Trsf());
92     }
93     ImageComposer_Image aResImg = anOp->process(anImage1, anImage2);
94     theImage->SetImage(aResImg);
95   }
96   // change the states of this and all depended images
97   theImage->MustBeUpdated(true);
98   SetMustBeUpdatedImages(theDoc);
99   theImage->MustBeUpdated(false);
100 }
101
102 void HYDROOperations_Factory::SetMustBeUpdatedImages(
103   Handle_HYDROData_Document theDoc) const
104 {
105   bool aChanged = true;
106   // iterate until there is no changes because images on all level of dependency must be updated
107   while(aChanged) {
108     aChanged = false;
109     HYDROData_Iterator anIter(theDoc, KIND_IMAGE);
110     for(; anIter.More(); anIter.Next()) {
111       Handle(HYDROData_Image) anImage = 
112         Handle(HYDROData_Image)::DownCast(anIter.Current());
113       if (!anImage->MustBeUpdated()) {
114         int a, aNBRefs = anImage->NbReferences();
115         for(a = 0; a < aNBRefs; a++) {
116           if (anImage->Reference(a)->MustBeUpdated()) {
117              // image references to updated => also must be updated
118              anImage->MustBeUpdated(true);
119              aChanged = true;
120           }
121         }
122       }
123     }
124   }
125 }