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