From: adv Date: Tue, 10 Sep 2013 05:31:56 +0000 (+0000) Subject: HYDROData package gas been mergrd eith HYDROOperations. X-Git-Tag: BR_hydro_v_0_1~52 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=31be23eddb92088fa3e40b00ae90bccf75b8be65;p=modules%2Fhydro.git HYDROData package gas been mergrd eith HYDROOperations. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 8396e2a4..ffb6e673 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,6 @@ find_package(SalomeCPPUNIT) set(HYDRO_salomeres_DATA share/salome/resources/hydro) add_subdirectory (src/HYDROData) -add_subdirectory (src/HYDROOperations) add_subdirectory (src/HYDROGUI) add_subdirectory (src/HYDROPy) diff --git a/HYDRO.sln b/HYDRO.sln index 52d0869c..c37bebb2 100644 --- a/HYDRO.sln +++ b/HYDRO.sln @@ -3,16 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 10.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HYDROGUI", "src\HYDROGUI\HYDROGUI.vcproj", "{D11F0AD0-D002-4A22-A8E6-3F906379206F}" ProjectSection(ProjectDependencies) = postProject {EB7B7816-4EA0-4E7D-A88A-1417DEB0FC1C} = {EB7B7816-4EA0-4E7D-A88A-1417DEB0FC1C} - {6F9309FA-A798-4F2A-A04B-133EA58E50A9} = {6F9309FA-A798-4F2A-A04B-133EA58E50A9} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HYDROData", "src\HYDROData\HYDROData.vcproj", "{EB7B7816-4EA0-4E7D-A88A-1417DEB0FC1C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HYDROOperations", "src\HYDROOperations\HYDROOperations.vcproj", "{6F9309FA-A798-4F2A-A04B-133EA58E50A9}" - ProjectSection(ProjectDependencies) = postProject - {EB7B7816-4EA0-4E7D-A88A-1417DEB0FC1C} = {EB7B7816-4EA0-4E7D-A88A-1417DEB0FC1C} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HYDROPy", "src\HYDROPy\HYDROPy.vcproj", "{72DE2E1A-BDE1-4BBE-8225-3D3DB2CC6C93}" EndProject Global @@ -29,10 +23,6 @@ Global {EB7B7816-4EA0-4E7D-A88A-1417DEB0FC1C}.Debug|Win32.Build.0 = Debug|Win32 {EB7B7816-4EA0-4E7D-A88A-1417DEB0FC1C}.Release|Win32.ActiveCfg = Debug|Win32 {EB7B7816-4EA0-4E7D-A88A-1417DEB0FC1C}.Release|Win32.Build.0 = Debug|Win32 - {6F9309FA-A798-4F2A-A04B-133EA58E50A9}.Debug|Win32.ActiveCfg = Debug|Win32 - {6F9309FA-A798-4F2A-A04B-133EA58E50A9}.Debug|Win32.Build.0 = Debug|Win32 - {6F9309FA-A798-4F2A-A04B-133EA58E50A9}.Release|Win32.ActiveCfg = Debug|Win32 - {6F9309FA-A798-4F2A-A04B-133EA58E50A9}.Release|Win32.Build.0 = Debug|Win32 {72DE2E1A-BDE1-4BBE-8225-3D3DB2CC6C93}.Debug|Win32.ActiveCfg = Debug|Win32 {72DE2E1A-BDE1-4BBE-8225-3D3DB2CC6C93}.Debug|Win32.Build.0 = Debug|Win32 {72DE2E1A-BDE1-4BBE-8225-3D3DB2CC6C93}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/src/HYDROData/CMakeLists.txt b/src/HYDROData/CMakeLists.txt index ba4f85aa..3c169ed6 100644 --- a/src/HYDROData/CMakeLists.txt +++ b/src/HYDROData/CMakeLists.txt @@ -12,6 +12,9 @@ set(PROJECT_HEADERS HYDROData_Polyline.h HYDROData_VisualState.h HYDROData_Tool.h + HYDROOperations.h + HYDROOperations_Factory.h + HYDROOperations_BSpline.h ) set(PROJECT_SOURCES @@ -25,12 +28,15 @@ set(PROJECT_SOURCES HYDROData_Polyline.cxx HYDROData_VisualState.cxx HYDROData_Tool.cxx + HYDROOperations_Factory.cxx + HYDROOperations_BSpline.cxx ) add_definitions( -DHYDRODATA_EXPORTS ${CAS_DEFINITIONS} ${QT_DEFINITIONS} + ${GUI_CXXFLAGS} ) include_directories( @@ -40,7 +46,7 @@ include_directories( ) add_library(HYDROData SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) -target_link_libraries(HYDROData ${CAS_OCAF} ${QT_LIBRARIES}) +target_link_libraries(HYDROData ${CAS_OCAF} ${QT_LIBRARIES} ${CAS_TKG3d} ${CAS_TKGeomBase} ${CAS_TKGeomAlgo} ${ImageComposer}) set(PROJECT_LIBRARIES HYDROData) @@ -53,6 +59,8 @@ if(CPPUNIT_IS_OK) test_HYDROData_Iterator.h test_HYDROData_Image.h test_HYDROData_Polyline.h + test_HYDROOperations_BSpline.h + test_HYDROOperations_Factory.h ) set(TEST_SOURCES @@ -62,11 +70,13 @@ if(CPPUNIT_IS_OK) test_HYDROData_Iterator.cxx test_HYDROData_Image.cxx test_HYDROData_Polyline.cxx + test_HYDROOperations_BSpline.cxx + test_HYDROOperations_Factory.cxx ) set(TEST_EXE test_HYDROData) include(../../CMake/CPPUnitTests.cmake) - target_link_libraries(test_HYDROData ${CAS_OCAF} ${QT_LIBRARIES} ${CPPUNIT_LIBS} HYDROData) + target_link_libraries(test_HYDROData ${CAS_OCAF} ${CAS_MODELER} ${QT_LIBRARIES} ${CPPUNIT_LIBS} HYDROData) endif(CPPUNIT_IS_OK) diff --git a/src/HYDROData/HYDROData.vcproj b/src/HYDROData/HYDROData.vcproj index 9310c556..3b659e3f 100644 --- a/src/HYDROData/HYDROData.vcproj +++ b/src/HYDROData/HYDROData.vcproj @@ -177,6 +177,18 @@ > + + + + + + + + + + + + diff --git a/src/HYDROData/HYDROOperations_BSpline.cxx b/src/HYDROData/HYDROOperations_BSpline.cxx new file mode 100644 index 00000000..376490da --- /dev/null +++ b/src/HYDROData/HYDROOperations_BSpline.cxx @@ -0,0 +1,58 @@ +#include + +#include +#include +#include +#include + +HYDROOperations_BSpline::HYDROOperations_BSpline( + QList& thePoints) +{ + // fill array for algorithm by the received coordinates + int aLen = thePoints.size() / 2; + Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt (1, aLen); + QList::iterator aListIter = thePoints.begin(); + for (int ind = 1; ind <= aLen; ind++) { + gp_Pnt aPnt(gp::Origin()); + aPnt.SetX(*aListIter); + aListIter++; + aPnt.SetY(*aListIter); + aListIter++; + aHCurvePoints->SetValue(ind, aPnt); + } + // compute BSpline + GeomAPI_Interpolate aGBC(aHCurvePoints, Standard_False, gp::Resolution()); + aGBC.Perform(); + if (aGBC.IsDone()) { + myCurve = aGBC.Curve(); + } +} + +QPainterPath HYDROOperations_BSpline::ComputePath() const +{ + QPainterPath aResult; + if (myCurve.IsNull()) // returns an empty Path if original curve is invalid + return aResult; + GeomConvert_BSplineCurveToBezierCurve aConverter(myCurve); + int a, aNumArcs = aConverter.NbArcs(); + for(a = 1; a <= aNumArcs; a++) { + Handle(Geom_BezierCurve) anArc = aConverter.Arc(a); + if (a == 1) { // set a start point + gp_Pnt aStart = anArc->StartPoint(); + aResult.moveTo(aStart.X(), aStart.Y()); + } + gp_Pnt anEnd = anArc->EndPoint(); + if (anArc->NbPoles() == 3) { // quadric segment in the path (pole 1 is start, pole 3 is end) + gp_Pnt aPole = anArc->Pole(2); + aResult.quadTo(aPole.X(), aPole.Y(), anEnd.X(), anEnd.Y()); + } else if (anArc->NbPoles() == 4) { // cubic segment (usually this is used) + gp_Pnt aPole1 = anArc->Pole(2); + gp_Pnt aPole2 = anArc->Pole(3); + aResult.cubicTo( + aPole1.X(), aPole1.Y(), aPole2.X(), aPole2.Y(), anEnd.X(), anEnd.Y()); + } else { // error, another number of poles is not supported + return QPainterPath(); + } + } + return aResult; +} diff --git a/src/HYDROData/HYDROOperations_BSpline.h b/src/HYDROData/HYDROOperations_BSpline.h new file mode 100644 index 00000000..47c3f305 --- /dev/null +++ b/src/HYDROData/HYDROOperations_BSpline.h @@ -0,0 +1,36 @@ +#ifndef HYDROOperations_BSpline_HeaderFile +#define HYDROOperations_BSpline_HeaderFile + +#include +#include +#include +#include + +/**\class HYDROOperations_BSpline + * + * \brief Allows to work with splines: create, convert to Qt ToolPath. + * + * Uses GEOM module for creation of BSplines, OCCT algorithms for + * manipulation and conversion. + */ + +class HYDRODATA_EXPORT HYDROOperations_BSpline +{ +public: + + //! Creates a spline by list of coordinates: pairs X and Y + //! \param thePoints coordinates in format X1, Y1, X2, Y2, etc. must be even number of elements + HYDROOperations_BSpline(QList& thePoints); + + //! Returns the BSpline curve passing through the points + //! \returns Null if Computation of BSpline was failed + Handle(Geom_BSplineCurve) Curve() const {return myCurve;} + + //! Performs conversion from BSpline curve to QPainterPath made from Bezier curves + //! \returns computed PainterPath, not stored in this class, so calling of this method is not fast + QPainterPath ComputePath() const; +private: + Handle(Geom_BSplineCurve) myCurve; ///< resulting BSpline, null if something is wrong +}; + +#endif diff --git a/src/HYDROData/HYDROOperations_Factory.cxx b/src/HYDROData/HYDROOperations_Factory.cxx new file mode 100644 index 00000000..bfbfbdbf --- /dev/null +++ b/src/HYDROData/HYDROOperations_Factory.cxx @@ -0,0 +1,128 @@ +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +// global instance +HYDROOperations_Factory* FACTORY = 0; + +HYDROOperations_Factory* HYDROOperations_Factory::Factory() +{ + if (!FACTORY) { + FACTORY = new HYDROOperations_Factory; + // default operations + REGISTER_HYDRO_OPERATION(ImageComposer_ColorMaskOperator) + REGISTER_HYDRO_OPERATION(ImageComposer_CropOperator) + REGISTER_HYDRO_OPERATION(ImageComposer_CutOperator) + REGISTER_HYDRO_OPERATION(ImageComposer_FuseOperator) + } + return FACTORY; +} + +ImageComposer_Operator* HYDROOperations_Factory::Operator(const QString theName) const +{ + if (myOps.contains(theName)) { + return myOps[theName]; + } + return NULL; +} + +void HYDROOperations_Factory::Register( + ImageComposer_Operator* theOperator) +{ + FACTORY->myOps[QString(typeid(*theOperator).name())] = theOperator; +} + +HYDROOperations_Factory::HYDROOperations_Factory() +{ +} + +ImageComposer_Operator* HYDROOperations_Factory::Operator( + Handle(HYDROData_Image) theImage) const +{ + // retreive operator instance by name + ImageComposer_Operator* anOp = Operator(theImage->OperatorName()); + if (!anOp) + return anOp; + // fill arguments of the operator from theImage + theImage->Args(); + anOp->setBinArgs(theImage->Args()); + return anOp; +} + +Handle(HYDROData_Image) HYDROOperations_Factory::CreateImage( + Handle(HYDROData_Document) theDoc, const ImageComposer_Operator* theOperator) +{ + // create an object + Handle(HYDROData_Image) anImage = + Handle(HYDROData_Image)::DownCast(theDoc->CreateObject(KIND_IMAGE)); + // get data from operation + if (theOperator) { + anImage->SetOperatorName(QString(typeid(*theOperator).name())); + anImage->SetArgs(theOperator->getBinArgs()); + } + return anImage; +} + +void HYDROOperations_Factory::UpdateImage( + Handle_HYDROData_Document theDoc, Handle(HYDROData_Image) theImage) +{ + // fill by arguments and process the operation + ImageComposer_Operator* anOp = Operator(theImage); + if (anOp) { // update image only if there is an operation + QTransform aTransform; + ImageComposer_Image anImage1; // first referenced image + if (theImage->NbReferences()) { + Handle(HYDROData_Image) anImage = theImage->Reference(0); + anImage1 = anImage->Image(); + anImage1.setTransform(anImage->Trsf()); + aTransform = anImage1.transform(); + } + ImageComposer_Image anImage2; // second referenced image + if (theImage->NbReferences() > 1) { + Handle(HYDROData_Image) anImage = theImage->Reference(1); + anImage2 = anImage->Image(); + anImage2.setTransform(anImage->Trsf()); + } + ImageComposer_Image aResImg = anOp->process(anImage1, anImage2); + theImage->SetImage(aResImg); + theImage->SetTrsf(aTransform); + } + // change the states of this and all depended images + theImage->MustBeUpdated(true); + SetMustBeUpdatedImages(theDoc); + theImage->MustBeUpdated(false); +} + +void HYDROOperations_Factory::SetMustBeUpdatedImages( + Handle_HYDROData_Document theDoc) const +{ + bool aChanged = true; + // iterate until there is no changes because images on all level of dependency must be updated + while(aChanged) { + aChanged = false; + HYDROData_Iterator anIter(theDoc, KIND_IMAGE); + for(; anIter.More(); anIter.Next()) { + Handle(HYDROData_Image) anImage = + Handle(HYDROData_Image)::DownCast(anIter.Current()); + if (!anImage->MustBeUpdated()) { + int a, aNBRefs = anImage->NbReferences(); + for(a = 0; a < aNBRefs; a++) { + if (anImage->Reference(a)->MustBeUpdated()) { + // image references to updated => also must be updated + anImage->MustBeUpdated(true); + aChanged = true; + } + } + } + } + } +} diff --git a/src/HYDROData/HYDROOperations_Factory.h b/src/HYDROData/HYDROOperations_Factory.h new file mode 100644 index 00000000..7ef2c0e0 --- /dev/null +++ b/src/HYDROData/HYDROOperations_Factory.h @@ -0,0 +1,98 @@ +#ifndef HYDROOperations_Factory_HeaderFile +#define HYDROOperations_Factory_HeaderFile + +#include +#include +#include + +class ImageComposer_Operator; +class Handle_HYDROData_Document; + +/**\class HYDROOperations_Factory + * + * \brief This class provides the unified management of operations on images. + * + * Object is created as one global instance and allows to register and launch + * all registered operations in general way. To register a new operation just + * call REGISTER_HYDRO_OPERATION(operation_name) in some method implementation. + * This macro will call constructor of this operation (it must inherit + * ImageComposer_Operator) and factory will set up arguments and call this + * operator by demand. + */ + +class HYDROOperations_Factory +{ +public: + + //! Returns the global factory + HYDRODATA_EXPORT static HYDROOperations_Factory* Factory(); + + /** + * Registers the operator by the name, used by REGISTER_HYDRO_OPERATION macro + * \param theOperator new instance of the operator that will be used for + * processing of operation with such kind + */ + HYDRODATA_EXPORT static void Register( + ImageComposer_Operator* theOperator); + + /** + * Creates a new Image object in the data structure by the operator data. + * \param theDoc document where it must be created + * \param theOperator base operator for this Image: will be used in "Update" to recompute the image + * \returns created object related to the data structure + */ + HYDRODATA_EXPORT Handle(HYDROData_Image) CreateImage( + Handle_HYDROData_Document theDoc, const ImageComposer_Operator* theOperator); + + /** + * Updates an Image object in the data structure. If it is changed, + * sets "MustBeUpdated" flag to other depended images. + * \param theDoc document of this image (needed to update other images flags) + * \param theImage the updated image + */ + HYDRODATA_EXPORT void UpdateImage( + Handle_HYDROData_Document theDoc, Handle(HYDROData_Image) theImage); + + /** + * Returns the operator, initialized by the properties of theImage + * \param theImage data structures object, that contains all arguments + * required for creation of operation + * \returns NULL if operator type is unknown + */ + HYDRODATA_EXPORT ImageComposer_Operator* Operator( + Handle(HYDROData_Image) theImage) const; + + +protected: + + //! Not public constructor that creates only one, global instance of this factory. + HYDROOperations_Factory(); + + /** + * Returns the appropriate operator by the name + * \param theName name of the operator, equals to the operation_name constructor + * \returns NULL if operator with such name is not registered yet + */ + ImageComposer_Operator* Operator(const QString theName) const; + + /** + * Enables "MustBeUpdated" flag for Images that are depended on "MustBeUpdated" images. + * \param theDoc document where this operation is performed + */ + void SetMustBeUpdatedImages(Handle_HYDROData_Document theDoc) const; + +private: + //! Map that stores all operators, isentified by strings + typedef QMap FactoryOperators; + + FactoryOperators myOps; ///< all operators stored by a factory +}; + +/** + * Macro that is used for registered operators, see C++ of this class to see + * example of hte registration. + */ +#define REGISTER_HYDRO_OPERATION(operation_name) \ + HYDROOperations_Factory::Factory()->Register(new operation_name); + +#endif diff --git a/src/HYDROData/test_HYDROOperations_BSpline.cxx b/src/HYDROData/test_HYDROOperations_BSpline.cxx new file mode 100644 index 00000000..b17590e2 --- /dev/null +++ b/src/HYDROData/test_HYDROOperations_BSpline.cxx @@ -0,0 +1,64 @@ +#include + +#include +#include +#include + +void test_HYDROOperations_BSpline::testCurve() +{ + // prepare points: function of sin(x) + QList aPoints; + double x; + for(x = 0; x < 6.28; x += 0.1) + aPoints<IsClosed()); + CPPUNIT_ASSERT_EQUAL(aBS->Continuity(), GeomAbs_C2); + // check that values of BSpline are not far from original "sin" function + // in all points of the curve + for(x = 0; x < 6.29; x += 0.001) { + double aDiff = aBS->Value(x).Y() - sin(aBS->Value(x).X()); + if (aDiff < 0) aDiff = -aDiff; + CPPUNIT_ASSERT(aDiff < 3.e-6); // this number is found manually + } +} + +void test_HYDROOperations_BSpline::testPath() +{ + // prepare points: function of sin(x) + static const double aScale = 10000000.; + QList aPoints; + double x; + for(x = 0; x < 6.28; x += 0.1) + aPoints< aPolyF = aPath.toSubpathPolygons(QTransform()); + QList::iterator aFIter = aPolyF.begin(); + for(; aFIter != aPolyF.end();aFIter++) { + QPolygon aPoly = aFIter->toPolygon(); + QPolygon::iterator aPoints = aPoly.begin(); + for(; aPoints != aPoly.end(); aPoints++) { + double aDiff = aPoints->y() / aScale - sin(aPoints->x() / aScale); + if (aDiff < 0) aDiff = -aDiff; + CPPUNIT_ASSERT(aDiff < 4.e-6); // this number is found manually + } + } +} diff --git a/src/HYDROData/test_HYDROOperations_BSpline.h b/src/HYDROData/test_HYDROOperations_BSpline.h new file mode 100644 index 00000000..6eb11056 --- /dev/null +++ b/src/HYDROData/test_HYDROOperations_BSpline.h @@ -0,0 +1,26 @@ +#include + +class test_HYDROOperations_BSpline : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(test_HYDROOperations_BSpline); + CPPUNIT_TEST(testCurve); + CPPUNIT_TEST(testPath); + CPPUNIT_TEST_SUITE_END(); + +private: + +public: + + void setUp() {} + + void tearDown() {} + + // checks generation of BSpline curve by points + void testCurve(); + + // checks generation of QPainterPath + void testPath(); + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(test_HYDROOperations_BSpline); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_HYDROOperations_BSpline, "HYDROOperations_BSpline"); diff --git a/src/HYDROData/test_HYDROOperations_Factory.cxx b/src/HYDROData/test_HYDROOperations_Factory.cxx new file mode 100644 index 00000000..0695cc33 --- /dev/null +++ b/src/HYDROData/test_HYDROOperations_Factory.cxx @@ -0,0 +1,61 @@ +#include + +#include +#include +#include + +#include +#include + +void test_HYDROOperations_Factory::testCreate() +{ + Handle(HYDROData_Document) aDoc = HYDROData_Document::Document(1); + + HYDROOperations_Factory* aFactory = HYDROOperations_Factory::Factory(); + CPPUNIT_ASSERT(aFactory); + Handle(HYDROData_Image) anImage = aFactory->CreateImage(aDoc, NULL); + CPPUNIT_ASSERT(!anImage.IsNull()); + CPPUNIT_ASSERT(anImage->Image().isNull()); + + aDoc->Close(); +} + +static QImage TestImage() { + QImage aPic(50, 40, QImage::Format_RGB32); + aPic.fill(Qt::white); + QPainter aPainter(&aPic); + aPainter.drawEllipse(6, 7, 38, 30); + aPainter.drawLine(0, 40, 10, 0); + aPainter.drawLine(10, 0, 25, 35); + aPainter.drawLine(25, 35, 40, 0); + aPainter.drawLine(40, 0, 50, 40); + return aPic; +} + +void test_HYDROOperations_Factory::testCrop() +{ + Handle(HYDROData_Document) aDoc = HYDROData_Document::Document(1); + HYDROOperations_Factory* aFactory = HYDROOperations_Factory::Factory(); + Handle(HYDROData_Image) anImage = aFactory->CreateImage(aDoc, NULL); + // prepare the original image and crop-path + QImage aPic = TestImage(); + anImage->SetImage(aPic); + QPainterPath aPath(QPointF(25, 0)); + aPath.lineTo(0, 20); + aPath.lineTo(25, 40); + aPath.lineTo(50, 20); + aPath.closeSubpath(); + // prepare Composer Operation + ImageComposer_CropOperator aCropOp; + aCropOp.setArgs(Qt::red, aPath); + // create crop - image + Handle(HYDROData_Image) aCrop = aFactory->CreateImage(aDoc, &aCropOp); + CPPUNIT_ASSERT(!aCrop.IsNull()); + aCrop->AppendReference(anImage); + aFactory->UpdateImage(aDoc, aCrop); + // check crop operation was performed + CPPUNIT_ASSERT(!aCrop->Image().isNull()); + CPPUNIT_ASSERT(aCrop->Image() != aPic); + + aDoc->Close(); +} diff --git a/src/HYDROData/test_HYDROOperations_Factory.h b/src/HYDROData/test_HYDROOperations_Factory.h new file mode 100644 index 00000000..fa7e9172 --- /dev/null +++ b/src/HYDROData/test_HYDROOperations_Factory.h @@ -0,0 +1,25 @@ +#include + +class test_HYDROOperations_Factory : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(test_HYDROOperations_Factory); + CPPUNIT_TEST(testCreate); + CPPUNIT_TEST(testCrop); + CPPUNIT_TEST_SUITE_END(); + +private: + +public: + + void setUp() {} + + void tearDown() {} + + // checks creation of images using null operators + void testCreate(); + + // checks creation of images using crop operator + void testCrop(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(test_HYDROOperations_Factory); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_HYDROOperations_Factory, "HYDROOperations_Factory"); diff --git a/src/HYDROGUI/HYDROGUI.vcproj b/src/HYDROGUI/HYDROGUI.vcproj index 36723c6e..6394a14c 100644 --- a/src/HYDROGUI/HYDROGUI.vcproj +++ b/src/HYDROGUI/HYDROGUI.vcproj @@ -1,7 +1,7 @@ diff --git a/src/HYDROOperations/CMakeLists.txt b/src/HYDROOperations/CMakeLists.txt deleted file mode 100644 index 8dda9f0f..00000000 --- a/src/HYDROOperations/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -include(../../CMake/Common.cmake) - -set(PROJECT_HEADERS - HYDROOperations.h - HYDROOperations_Factory.h - HYDROOperations_BSpline.h -) - -set(PROJECT_SOURCES - HYDROOperations_Factory.cxx - HYDROOperations_BSpline.cxx -) - -add_definitions( - -DHYDROOPERATIONS_EXPORTS - ${CAS_DEFINITIONS} - ${QT_DEFINITIONS} - ${GUI_CXXFLAGS} -) - -include_directories( - ${CAS_INCLUDE_DIRS} - ${QT_INCLUDES} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../HYDROData -) - -add_library(HYDROOperations SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) -target_link_libraries(HYDROOperations ${CAS_TKG3d} ${CAS_TKGeomBase} ${CAS_TKGeomAlgo} ${ImageComposer} HYDROData) - -set(PROJECT_LIBRARIES HYDROOperations) - -# tests -if(CPPUNIT_IS_OK) - - set(TEST_HEADERS - test_HYDROOperations_BSpline.h - test_HYDROOperations_Factory.h - ) - - set(TEST_SOURCES - test_HYDROOperations_Main.cxx - test_HYDROOperations_BSpline.cxx - test_HYDROOperations_Factory.cxx - ) - - set(TEST_EXE test_HYDROOperations) - include(../../CMake/CPPUnitTests.cmake) - target_link_libraries(test_HYDROOperations ${CAS_MODELER} ${QT_LIBRARIES} ${CPPUNIT_LIBS} HYDROOperations) - -endif(CPPUNIT_IS_OK) - -include(../../CMake/CommonInstall.cmake) diff --git a/src/HYDROOperations/HYDROOperations.h b/src/HYDROOperations/HYDROOperations.h deleted file mode 100644 index feeaec5a..00000000 --- a/src/HYDROOperations/HYDROOperations.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef HYDROOPERATIONS_H -#define HYDROOPERATIONS_H - -#if defined HYDROOPERATIONS_EXPORTS -#if defined WIN32 -#define HYDROOPERATIONS_EXPORT __declspec( dllexport ) -#else -#define HYDROOPERATIONS_EXPORT -#endif -#else -#if defined WIN32 -#define HYDROOPERATIONS_EXPORT __declspec( dllimport ) -#else -#define HYDROOPERATIONS_EXPORT -#endif -#endif - -#endif diff --git a/src/HYDROOperations/HYDROOperations.vcproj b/src/HYDROOperations/HYDROOperations.vcproj deleted file mode 100644 index ac2828d7..00000000 --- a/src/HYDROOperations/HYDROOperations.vcproj +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/HYDROOperations/HYDROOperations_BSpline.cxx b/src/HYDROOperations/HYDROOperations_BSpline.cxx deleted file mode 100644 index 376490da..00000000 --- a/src/HYDROOperations/HYDROOperations_BSpline.cxx +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#include -#include -#include -#include - -HYDROOperations_BSpline::HYDROOperations_BSpline( - QList& thePoints) -{ - // fill array for algorithm by the received coordinates - int aLen = thePoints.size() / 2; - Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt (1, aLen); - QList::iterator aListIter = thePoints.begin(); - for (int ind = 1; ind <= aLen; ind++) { - gp_Pnt aPnt(gp::Origin()); - aPnt.SetX(*aListIter); - aListIter++; - aPnt.SetY(*aListIter); - aListIter++; - aHCurvePoints->SetValue(ind, aPnt); - } - // compute BSpline - GeomAPI_Interpolate aGBC(aHCurvePoints, Standard_False, gp::Resolution()); - aGBC.Perform(); - if (aGBC.IsDone()) { - myCurve = aGBC.Curve(); - } -} - -QPainterPath HYDROOperations_BSpline::ComputePath() const -{ - QPainterPath aResult; - if (myCurve.IsNull()) // returns an empty Path if original curve is invalid - return aResult; - GeomConvert_BSplineCurveToBezierCurve aConverter(myCurve); - int a, aNumArcs = aConverter.NbArcs(); - for(a = 1; a <= aNumArcs; a++) { - Handle(Geom_BezierCurve) anArc = aConverter.Arc(a); - if (a == 1) { // set a start point - gp_Pnt aStart = anArc->StartPoint(); - aResult.moveTo(aStart.X(), aStart.Y()); - } - gp_Pnt anEnd = anArc->EndPoint(); - if (anArc->NbPoles() == 3) { // quadric segment in the path (pole 1 is start, pole 3 is end) - gp_Pnt aPole = anArc->Pole(2); - aResult.quadTo(aPole.X(), aPole.Y(), anEnd.X(), anEnd.Y()); - } else if (anArc->NbPoles() == 4) { // cubic segment (usually this is used) - gp_Pnt aPole1 = anArc->Pole(2); - gp_Pnt aPole2 = anArc->Pole(3); - aResult.cubicTo( - aPole1.X(), aPole1.Y(), aPole2.X(), aPole2.Y(), anEnd.X(), anEnd.Y()); - } else { // error, another number of poles is not supported - return QPainterPath(); - } - } - return aResult; -} diff --git a/src/HYDROOperations/HYDROOperations_BSpline.h b/src/HYDROOperations/HYDROOperations_BSpline.h deleted file mode 100644 index 0fb9134f..00000000 --- a/src/HYDROOperations/HYDROOperations_BSpline.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HYDROOperations_BSpline_HeaderFile -#define HYDROOperations_BSpline_HeaderFile - -#include -#include -#include -#include - -/**\class HYDROOperations_BSpline - * - * \brief Allows to work with splines: create, convert to Qt ToolPath. - * - * Uses GEOM module for creation of BSplines, OCCT algorithms for - * manipulation and conversion. - */ - -class HYDROOPERATIONS_EXPORT HYDROOperations_BSpline -{ -public: - - //! Creates a spline by list of coordinates: pairs X and Y - //! \param thePoints coordinates in format X1, Y1, X2, Y2, etc. must be even number of elements - HYDROOperations_BSpline(QList& thePoints); - - //! Returns the BSpline curve passing through the points - //! \returns Null if Computation of BSpline was failed - Handle(Geom_BSplineCurve) Curve() const {return myCurve;} - - //! Performs conversion from BSpline curve to QPainterPath made from Bezier curves - //! \returns computed PainterPath, not stored in this class, so calling of this method is not fast - QPainterPath ComputePath() const; -private: - Handle(Geom_BSplineCurve) myCurve; ///< resulting BSpline, null if something is wrong -}; - -#endif diff --git a/src/HYDROOperations/HYDROOperations_Factory.cxx b/src/HYDROOperations/HYDROOperations_Factory.cxx deleted file mode 100644 index bfbfbdbf..00000000 --- a/src/HYDROOperations/HYDROOperations_Factory.cxx +++ /dev/null @@ -1,128 +0,0 @@ -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include - -// global instance -HYDROOperations_Factory* FACTORY = 0; - -HYDROOperations_Factory* HYDROOperations_Factory::Factory() -{ - if (!FACTORY) { - FACTORY = new HYDROOperations_Factory; - // default operations - REGISTER_HYDRO_OPERATION(ImageComposer_ColorMaskOperator) - REGISTER_HYDRO_OPERATION(ImageComposer_CropOperator) - REGISTER_HYDRO_OPERATION(ImageComposer_CutOperator) - REGISTER_HYDRO_OPERATION(ImageComposer_FuseOperator) - } - return FACTORY; -} - -ImageComposer_Operator* HYDROOperations_Factory::Operator(const QString theName) const -{ - if (myOps.contains(theName)) { - return myOps[theName]; - } - return NULL; -} - -void HYDROOperations_Factory::Register( - ImageComposer_Operator* theOperator) -{ - FACTORY->myOps[QString(typeid(*theOperator).name())] = theOperator; -} - -HYDROOperations_Factory::HYDROOperations_Factory() -{ -} - -ImageComposer_Operator* HYDROOperations_Factory::Operator( - Handle(HYDROData_Image) theImage) const -{ - // retreive operator instance by name - ImageComposer_Operator* anOp = Operator(theImage->OperatorName()); - if (!anOp) - return anOp; - // fill arguments of the operator from theImage - theImage->Args(); - anOp->setBinArgs(theImage->Args()); - return anOp; -} - -Handle(HYDROData_Image) HYDROOperations_Factory::CreateImage( - Handle(HYDROData_Document) theDoc, const ImageComposer_Operator* theOperator) -{ - // create an object - Handle(HYDROData_Image) anImage = - Handle(HYDROData_Image)::DownCast(theDoc->CreateObject(KIND_IMAGE)); - // get data from operation - if (theOperator) { - anImage->SetOperatorName(QString(typeid(*theOperator).name())); - anImage->SetArgs(theOperator->getBinArgs()); - } - return anImage; -} - -void HYDROOperations_Factory::UpdateImage( - Handle_HYDROData_Document theDoc, Handle(HYDROData_Image) theImage) -{ - // fill by arguments and process the operation - ImageComposer_Operator* anOp = Operator(theImage); - if (anOp) { // update image only if there is an operation - QTransform aTransform; - ImageComposer_Image anImage1; // first referenced image - if (theImage->NbReferences()) { - Handle(HYDROData_Image) anImage = theImage->Reference(0); - anImage1 = anImage->Image(); - anImage1.setTransform(anImage->Trsf()); - aTransform = anImage1.transform(); - } - ImageComposer_Image anImage2; // second referenced image - if (theImage->NbReferences() > 1) { - Handle(HYDROData_Image) anImage = theImage->Reference(1); - anImage2 = anImage->Image(); - anImage2.setTransform(anImage->Trsf()); - } - ImageComposer_Image aResImg = anOp->process(anImage1, anImage2); - theImage->SetImage(aResImg); - theImage->SetTrsf(aTransform); - } - // change the states of this and all depended images - theImage->MustBeUpdated(true); - SetMustBeUpdatedImages(theDoc); - theImage->MustBeUpdated(false); -} - -void HYDROOperations_Factory::SetMustBeUpdatedImages( - Handle_HYDROData_Document theDoc) const -{ - bool aChanged = true; - // iterate until there is no changes because images on all level of dependency must be updated - while(aChanged) { - aChanged = false; - HYDROData_Iterator anIter(theDoc, KIND_IMAGE); - for(; anIter.More(); anIter.Next()) { - Handle(HYDROData_Image) anImage = - Handle(HYDROData_Image)::DownCast(anIter.Current()); - if (!anImage->MustBeUpdated()) { - int a, aNBRefs = anImage->NbReferences(); - for(a = 0; a < aNBRefs; a++) { - if (anImage->Reference(a)->MustBeUpdated()) { - // image references to updated => also must be updated - anImage->MustBeUpdated(true); - aChanged = true; - } - } - } - } - } -} diff --git a/src/HYDROOperations/HYDROOperations_Factory.h b/src/HYDROOperations/HYDROOperations_Factory.h deleted file mode 100644 index 0416e3b6..00000000 --- a/src/HYDROOperations/HYDROOperations_Factory.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef HYDROOperations_Factory_HeaderFile -#define HYDROOperations_Factory_HeaderFile - -#include -#include -#include - -class ImageComposer_Operator; -class Handle_HYDROData_Document; - -/**\class HYDROOperations_Factory - * - * \brief This class provides the unified management of operations on images. - * - * Object is created as one global instance and allows to register and launch - * all registered operations in general way. To register a new operation just - * call REGISTER_HYDRO_OPERATION(operation_name) in some method implementation. - * This macro will call constructor of this operation (it must inherit - * ImageComposer_Operator) and factory will set up arguments and call this - * operator by demand. - */ - -class HYDROOperations_Factory -{ -public: - - //! Returns the global factory - HYDROOPERATIONS_EXPORT static HYDROOperations_Factory* Factory(); - - /** - * Registers the operator by the name, used by REGISTER_HYDRO_OPERATION macro - * \param theOperator new instance of the operator that will be used for - * processing of operation with such kind - */ - HYDROOPERATIONS_EXPORT static void Register( - ImageComposer_Operator* theOperator); - - /** - * Creates a new Image object in the data structure by the operator data. - * \param theDoc document where it must be created - * \param theOperator base operator for this Image: will be used in "Update" to recompute the image - * \returns created object related to the data structure - */ - HYDROOPERATIONS_EXPORT Handle(HYDROData_Image) CreateImage( - Handle_HYDROData_Document theDoc, const ImageComposer_Operator* theOperator); - - /** - * Updates an Image object in the data structure. If it is changed, - * sets "MustBeUpdated" flag to other depended images. - * \param theDoc document of this image (needed to update other images flags) - * \param theImage the updated image - */ - HYDROOPERATIONS_EXPORT void UpdateImage( - Handle_HYDROData_Document theDoc, Handle(HYDROData_Image) theImage); - - /** - * Returns the operator, initialized by the properties of theImage - * \param theImage data structures object, that contains all arguments - * required for creation of operation - * \returns NULL if operator type is unknown - */ - HYDROOPERATIONS_EXPORT ImageComposer_Operator* Operator( - Handle(HYDROData_Image) theImage) const; - - -protected: - - //! Not public constructor that creates only one, global instance of this factory. - HYDROOperations_Factory(); - - /** - * Returns the appropriate operator by the name - * \param theName name of the operator, equals to the operation_name constructor - * \returns NULL if operator with such name is not registered yet - */ - ImageComposer_Operator* Operator(const QString theName) const; - - /** - * Enables "MustBeUpdated" flag for Images that are depended on "MustBeUpdated" images. - * \param theDoc document where this operation is performed - */ - void SetMustBeUpdatedImages(Handle_HYDROData_Document theDoc) const; - -private: - //! Map that stores all operators, isentified by strings - typedef QMap FactoryOperators; - - FactoryOperators myOps; ///< all operators stored by a factory -}; - -/** - * Macro that is used for registered operators, see C++ of this class to see - * example of hte registration. - */ -#define REGISTER_HYDRO_OPERATION(operation_name) \ - HYDROOperations_Factory::Factory()->Register(new operation_name); - -#endif diff --git a/src/HYDROOperations/test_HYDROOperations_BSpline.cxx b/src/HYDROOperations/test_HYDROOperations_BSpline.cxx deleted file mode 100644 index b17590e2..00000000 --- a/src/HYDROOperations/test_HYDROOperations_BSpline.cxx +++ /dev/null @@ -1,64 +0,0 @@ -#include - -#include -#include -#include - -void test_HYDROOperations_BSpline::testCurve() -{ - // prepare points: function of sin(x) - QList aPoints; - double x; - for(x = 0; x < 6.28; x += 0.1) - aPoints<IsClosed()); - CPPUNIT_ASSERT_EQUAL(aBS->Continuity(), GeomAbs_C2); - // check that values of BSpline are not far from original "sin" function - // in all points of the curve - for(x = 0; x < 6.29; x += 0.001) { - double aDiff = aBS->Value(x).Y() - sin(aBS->Value(x).X()); - if (aDiff < 0) aDiff = -aDiff; - CPPUNIT_ASSERT(aDiff < 3.e-6); // this number is found manually - } -} - -void test_HYDROOperations_BSpline::testPath() -{ - // prepare points: function of sin(x) - static const double aScale = 10000000.; - QList aPoints; - double x; - for(x = 0; x < 6.28; x += 0.1) - aPoints< aPolyF = aPath.toSubpathPolygons(QTransform()); - QList::iterator aFIter = aPolyF.begin(); - for(; aFIter != aPolyF.end();aFIter++) { - QPolygon aPoly = aFIter->toPolygon(); - QPolygon::iterator aPoints = aPoly.begin(); - for(; aPoints != aPoly.end(); aPoints++) { - double aDiff = aPoints->y() / aScale - sin(aPoints->x() / aScale); - if (aDiff < 0) aDiff = -aDiff; - CPPUNIT_ASSERT(aDiff < 4.e-6); // this number is found manually - } - } -} diff --git a/src/HYDROOperations/test_HYDROOperations_BSpline.h b/src/HYDROOperations/test_HYDROOperations_BSpline.h deleted file mode 100644 index 6eb11056..00000000 --- a/src/HYDROOperations/test_HYDROOperations_BSpline.h +++ /dev/null @@ -1,26 +0,0 @@ -#include - -class test_HYDROOperations_BSpline : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(test_HYDROOperations_BSpline); - CPPUNIT_TEST(testCurve); - CPPUNIT_TEST(testPath); - CPPUNIT_TEST_SUITE_END(); - -private: - -public: - - void setUp() {} - - void tearDown() {} - - // checks generation of BSpline curve by points - void testCurve(); - - // checks generation of QPainterPath - void testPath(); - -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(test_HYDROOperations_BSpline); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_HYDROOperations_BSpline, "HYDROOperations_BSpline"); diff --git a/src/HYDROOperations/test_HYDROOperations_Factory.cxx b/src/HYDROOperations/test_HYDROOperations_Factory.cxx deleted file mode 100644 index 0695cc33..00000000 --- a/src/HYDROOperations/test_HYDROOperations_Factory.cxx +++ /dev/null @@ -1,61 +0,0 @@ -#include - -#include -#include -#include - -#include -#include - -void test_HYDROOperations_Factory::testCreate() -{ - Handle(HYDROData_Document) aDoc = HYDROData_Document::Document(1); - - HYDROOperations_Factory* aFactory = HYDROOperations_Factory::Factory(); - CPPUNIT_ASSERT(aFactory); - Handle(HYDROData_Image) anImage = aFactory->CreateImage(aDoc, NULL); - CPPUNIT_ASSERT(!anImage.IsNull()); - CPPUNIT_ASSERT(anImage->Image().isNull()); - - aDoc->Close(); -} - -static QImage TestImage() { - QImage aPic(50, 40, QImage::Format_RGB32); - aPic.fill(Qt::white); - QPainter aPainter(&aPic); - aPainter.drawEllipse(6, 7, 38, 30); - aPainter.drawLine(0, 40, 10, 0); - aPainter.drawLine(10, 0, 25, 35); - aPainter.drawLine(25, 35, 40, 0); - aPainter.drawLine(40, 0, 50, 40); - return aPic; -} - -void test_HYDROOperations_Factory::testCrop() -{ - Handle(HYDROData_Document) aDoc = HYDROData_Document::Document(1); - HYDROOperations_Factory* aFactory = HYDROOperations_Factory::Factory(); - Handle(HYDROData_Image) anImage = aFactory->CreateImage(aDoc, NULL); - // prepare the original image and crop-path - QImage aPic = TestImage(); - anImage->SetImage(aPic); - QPainterPath aPath(QPointF(25, 0)); - aPath.lineTo(0, 20); - aPath.lineTo(25, 40); - aPath.lineTo(50, 20); - aPath.closeSubpath(); - // prepare Composer Operation - ImageComposer_CropOperator aCropOp; - aCropOp.setArgs(Qt::red, aPath); - // create crop - image - Handle(HYDROData_Image) aCrop = aFactory->CreateImage(aDoc, &aCropOp); - CPPUNIT_ASSERT(!aCrop.IsNull()); - aCrop->AppendReference(anImage); - aFactory->UpdateImage(aDoc, aCrop); - // check crop operation was performed - CPPUNIT_ASSERT(!aCrop->Image().isNull()); - CPPUNIT_ASSERT(aCrop->Image() != aPic); - - aDoc->Close(); -} diff --git a/src/HYDROOperations/test_HYDROOperations_Factory.h b/src/HYDROOperations/test_HYDROOperations_Factory.h deleted file mode 100644 index fa7e9172..00000000 --- a/src/HYDROOperations/test_HYDROOperations_Factory.h +++ /dev/null @@ -1,25 +0,0 @@ -#include - -class test_HYDROOperations_Factory : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(test_HYDROOperations_Factory); - CPPUNIT_TEST(testCreate); - CPPUNIT_TEST(testCrop); - CPPUNIT_TEST_SUITE_END(); - -private: - -public: - - void setUp() {} - - void tearDown() {} - - // checks creation of images using null operators - void testCreate(); - - // checks creation of images using crop operator - void testCrop(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(test_HYDROOperations_Factory); -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_HYDROOperations_Factory, "HYDROOperations_Factory"); diff --git a/src/HYDROOperations/test_HYDROOperations_Main.cxx b/src/HYDROOperations/test_HYDROOperations_Main.cxx deleted file mode 100644 index 95900832..00000000 --- a/src/HYDROOperations/test_HYDROOperations_Main.cxx +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -int - main( int argc, char* argv[] ) -{ - // to perform "drawing" qt tests - QApplication app(argc, argv); - - std::string testPath = (argc > 1) ? std::string(argv[1]) : ""; - - // Create the event manager and test controller - CppUnit::TestResult controller; - - // Add a listener that colllects test result - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - // Add a listener that print dots as test run. - CppUnit::TextTestProgressListener progress; - controller.addListener( &progress ); - - CppUnit::TestFactoryRegistry& registry = - CppUnit::TestFactoryRegistry::getRegistry(); - // Add the top suite to the test runner - CppUnit::TestRunner runner; - runner.addTest( registry.makeTest() ); - try - { - std::cout << "Running " << testPath; - runner.run( controller, testPath ); - - std::cerr << std::endl; - - // Print test in a compiler compatible format. - CppUnit::CompilerOutputter outputter( &result, std::cerr ); - outputter.write(); - } - catch ( std::invalid_argument &e ) // Test path not resolved - { - std::cerr << std::endl - << "ERROR: " << e.what() - << std::endl; - return 0; - } - - return result.wasSuccessful() ? 0 : 1; -}