├── .gitattributes ├── .gitignore ├── FlowProjects └── domainReduce.flow ├── NodeEditorPro.sln ├── NodeEditorPro ├── DefaultStyle.json ├── Halcon2105.props ├── NodeEditorPro.vcxproj ├── NodeEditorPro.vcxproj.filters ├── examples │ ├── calculator │ │ ├── AdditionModel.hpp │ │ ├── CMakeLists.txt │ │ ├── Converters.cpp │ │ ├── Converters.hpp │ │ ├── DecimalData.hpp │ │ ├── DivisionModel.hpp │ │ ├── IntegerData.hpp │ │ ├── MathNodes.hpp │ │ ├── MathOperationDataModel.cpp │ │ ├── MathOperationDataModel.hpp │ │ ├── ModuloModel.cpp │ │ ├── ModuloModel.hpp │ │ ├── MultiplicationModel.hpp │ │ ├── NumberDisplayDataModel.cpp │ │ ├── NumberDisplayDataModel.hpp │ │ ├── NumberSourceDataModel.cpp │ │ ├── NumberSourceDataModel.hpp │ │ └── SubtractionModel.hpp │ ├── halcon │ │ ├── HImageDLSegmentModel.cpp │ │ ├── HImageDLSegmentModel.hpp │ │ ├── HImageData.hpp │ │ ├── HImageFolderModel.cpp │ │ ├── HImageFolderModel.hpp │ │ ├── HImageLoaderModel.cpp │ │ ├── HImageLoaderModel.hpp │ │ ├── HImageRGB2GrayModel.cpp │ │ ├── HImageRGB2GrayModel.hpp │ │ ├── HImageReduceDomainModel.cpp │ │ ├── HImageReduceDomainModel.hpp │ │ ├── HImageShowModel.cpp │ │ ├── HImageShowModel.hpp │ │ ├── HImageSplitChanelModel.cpp │ │ ├── HImageSplitChanelModel.hpp │ │ ├── HImageThresholdModel.cpp │ │ ├── HImageThresholdModel.hpp │ │ ├── HImageViewWidget.cpp │ │ ├── HImageViewWidget.hpp │ │ ├── HObjectData.hpp │ │ ├── HRegionConnectModel.cpp │ │ ├── HRegionConnectModel.hpp │ │ ├── HRegionData.hpp │ │ ├── HRegionDifferenceModel.cpp │ │ ├── HRegionDifferenceModel.hpp │ │ ├── HRegionFillUpShapeModel.cpp │ │ ├── HRegionFillUpShapeModel.hpp │ │ ├── HRegionOpenCircleModel.cpp │ │ ├── HRegionOpenCircleModel.hpp │ │ ├── HRegionSelectModel.cpp │ │ ├── HRegionSelectModel.hpp │ │ ├── HRegionSelectShapeStdModel.cpp │ │ ├── HRegionSelectShapeStdModel.hpp │ │ ├── HRegionShapeTransModel.cpp │ │ ├── HRegionShapeTransModel.hpp │ │ ├── HRegionUnionModel.cpp │ │ ├── HRegionUnionModel.hpp │ │ └── HalconNodes.hpp │ └── images │ │ ├── ImageLoaderModel.cpp │ │ ├── ImageLoaderModel.hpp │ │ ├── ImageShowModel.cpp │ │ ├── ImageShowModel.hpp │ │ ├── PixmapData.hpp │ │ ├── VisionFlowWidget.cpp │ │ ├── VisionFlowWidget.hpp │ │ └── main.cpp ├── halcon20.11_x64_cpp.props ├── include │ └── nodes │ │ ├── Compiler.hpp │ │ ├── Connection.hpp │ │ ├── ConnectionGeometry.hpp │ │ ├── ConnectionGraphicsObject.hpp │ │ ├── ConnectionState.hpp │ │ ├── ConnectionStyle.hpp │ │ ├── DataModelRegistry.hpp │ │ ├── Export.hpp │ │ ├── FlowScene.hpp │ │ ├── FlowView.hpp │ │ ├── FlowViewStyle.hpp │ │ ├── Node.hpp │ │ ├── NodeData.hpp │ │ ├── NodeDataModel.hpp │ │ ├── NodeGeometry.hpp │ │ ├── NodeGraphicsObject.hpp │ │ ├── NodePainterDelegate.hpp │ │ ├── NodeState.hpp │ │ ├── NodeStyle.hpp │ │ ├── OperatingSystem.hpp │ │ ├── PortType.hpp │ │ ├── QStringStdHash.hpp │ │ ├── QUuidStdHash.hpp │ │ ├── Serializable.hpp │ │ ├── Style.hpp │ │ ├── StyleCollection.hpp │ │ ├── TypeConverter.hpp │ │ └── memory.hpp ├── resources │ ├── DefaultStyle - 副本.json │ ├── DefaultStyle.json │ ├── convert.png │ ├── logo.png │ └── resources.qrc ├── showcase │ ├── ReduceDomain.gif │ ├── ReduceDomain.mp4 │ ├── draw_shape_view.png │ ├── reduceNode.png │ ├── selectBallTest.png │ ├── selectRegionNode.png │ ├── showcase1.gif │ ├── showcase2.mp4 │ ├── showcase3.gif │ ├── showcase4.gif │ ├── showcase5.png │ └── showcase6.mp4 └── src │ ├── Connection.cpp │ ├── ConnectionBlurEffect.cpp │ ├── ConnectionBlurEffect.hpp │ ├── ConnectionGeometry.cpp │ ├── ConnectionGraphicsObject.cpp │ ├── ConnectionPainter.cpp │ ├── ConnectionPainter.hpp │ ├── ConnectionState.cpp │ ├── ConnectionStyle.cpp │ ├── DataModelRegistry.cpp │ ├── FlowScene.cpp │ ├── FlowView.cpp │ ├── FlowViewStyle.cpp │ ├── Node.cpp │ ├── NodeConnectionInteraction.cpp │ ├── NodeConnectionInteraction.hpp │ ├── NodeDataModel.cpp │ ├── NodeGeometry.cpp │ ├── NodeGraphicsObject.cpp │ ├── NodePainter.cpp │ ├── NodePainter.hpp │ ├── NodeState.cpp │ ├── NodeStyle.cpp │ ├── Properties.cpp │ ├── Properties.hpp │ ├── QDataStreamPhaser.cpp │ ├── QDataStreamPhaser.hpp │ ├── QJsonParser.cpp │ ├── QJsonParser.hpp │ └── StyleCollection.cpp ├── README.md └── ShapeDrawer ├── DrawShapeView.cpp ├── DrawShapeView.hpp ├── DrawViewParams.h ├── ShapeControlItem.cpp ├── ShapeControlItem.h ├── ShapeItemBase.cpp ├── ShapeItemBase.h ├── ShapeItemLine.cpp ├── ShapeItemLine.h ├── ShapeItemPolygon.cpp ├── ShapeItemPolygon.h ├── ShapeItemRect1.cpp ├── ShapeItemRect1.h ├── ShapeItemRect2.cpp └── ShapeItemRect2.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /NodeEditorPro.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32825.248 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NodeEditorPro", "NodeEditorPro\NodeEditorPro.vcxproj", "{4911AD57-2763-4EDF-9C7C-2E197137BE8B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {4911AD57-2763-4EDF-9C7C-2E197137BE8B}.Debug|x64.ActiveCfg = Debug|x64 15 | {4911AD57-2763-4EDF-9C7C-2E197137BE8B}.Debug|x64.Build.0 = Debug|x64 16 | {4911AD57-2763-4EDF-9C7C-2E197137BE8B}.Release|x64.ActiveCfg = Release|x64 17 | {4911AD57-2763-4EDF-9C7C-2E197137BE8B}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {26A3A5F1-B946-441D-97D3-C988346DDEF3} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /NodeEditorPro/Halcon2105.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | E:\CodeDeps\Halcon2105Cpp\include;E:\CodeDeps\Halcon2105Cpp\include\halconcpp;E:\CodeDeps\Halcon2105Cpp\;%(AdditionalIncludeDirectories) 9 | 10 | 11 | E:\CodeDeps\Halcon2105Cpp\lib;%(AdditionalLibraryDirectories) 12 | halconcpp.lib;halcon.lib;%(AdditionalDependencies) 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/AdditionModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "NodeDataModel.hpp" 8 | 9 | #include "MathOperationDataModel.hpp" 10 | #include "DecimalData.hpp" 11 | 12 | /// The model dictates the number of inputs and outputs for the Node. 13 | /// In this example it has no logic. 14 | class AdditionModel : public MathOperationDataModel 15 | { 16 | public: 17 | 18 | virtual 19 | ~AdditionModel() {} 20 | 21 | public: 22 | 23 | QString 24 | caption() const override 25 | { 26 | return QStringLiteral("加法"); 27 | } 28 | 29 | QString 30 | name() const override 31 | { 32 | return QStringLiteral("加法"); 33 | } 34 | 35 | private: 36 | 37 | void 38 | compute() override 39 | { 40 | PortIndex const outPortIndex = 0; 41 | 42 | auto n1 = _number1.lock(); 43 | auto n2 = _number2.lock(); 44 | 45 | if (n1 && n2) 46 | { 47 | modelValidationState = NodeValidationState::Valid; 48 | modelValidationError = QString(); 49 | _result = std::make_shared(n1->number() + 50 | n2->number()); 51 | } 52 | else 53 | { 54 | modelValidationState = NodeValidationState::Warning; 55 | modelValidationError = QStringLiteral("未连接或运行失败!"); 56 | _result.reset(); 57 | } 58 | 59 | Q_EMIT dataUpdated(outPortIndex); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB_RECURSE CPPS ./*.cpp ) 2 | 3 | add_executable(calculator ${CPPS}) 4 | 5 | target_link_libraries(calculator nodes) 6 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/Converters.cpp: -------------------------------------------------------------------------------- 1 | #include "Converters.hpp" 2 | 3 | #include 4 | 5 | #include "DecimalData.hpp" 6 | #include "IntegerData.hpp" 7 | 8 | 9 | std::shared_ptr 10 | DecimalToIntegerConverter:: 11 | operator()(std::shared_ptr data) 12 | { 13 | auto numberData = 14 | std::dynamic_pointer_cast(data); 15 | 16 | if (numberData) 17 | { 18 | _integer = std::make_shared(numberData->number()); 19 | } 20 | else 21 | { 22 | _integer.reset(); 23 | } 24 | 25 | return _integer; 26 | } 27 | 28 | 29 | std::shared_ptr 30 | IntegerToDecimalConverter:: 31 | operator()(std::shared_ptr data) 32 | { 33 | auto numberData = 34 | std::dynamic_pointer_cast(data); 35 | 36 | if (numberData) 37 | { 38 | _decimal = std::make_shared(numberData->number()); 39 | } 40 | else 41 | { 42 | _decimal.reset(); 43 | } 44 | 45 | return _decimal; 46 | } 47 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/Converters.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DecimalData.hpp" 4 | #include "IntegerData.hpp" 5 | 6 | using QtNodes::PortType; 7 | using QtNodes::PortIndex; 8 | using QtNodes::NodeData; 9 | using QtNodes::NodeDataType; 10 | using QtNodes::NodeDataModel; 11 | 12 | class DecimalData; 13 | class IntegerData; 14 | 15 | 16 | class DecimalToIntegerConverter 17 | { 18 | 19 | public: 20 | 21 | std::shared_ptr 22 | operator()(std::shared_ptr data); 23 | 24 | private: 25 | 26 | std::shared_ptr _integer; 27 | }; 28 | 29 | 30 | class IntegerToDecimalConverter 31 | { 32 | 33 | public: 34 | 35 | std::shared_ptr 36 | operator()(std::shared_ptr data); 37 | 38 | private: 39 | 40 | std::shared_ptr _decimal; 41 | }; 42 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/DecimalData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NodeDataModel.hpp" 4 | 5 | using QtNodes::NodeDataType; 6 | using QtNodes::NodeData; 7 | 8 | /// The class can potentially incapsulate any user data which 9 | /// need to be transferred within the Node Editor graph 10 | class DecimalData : public NodeData 11 | { 12 | public: 13 | 14 | DecimalData() 15 | : _number(0.0) 16 | {} 17 | 18 | DecimalData(double const number) 19 | : _number(number) 20 | {} 21 | 22 | NodeDataType type() const override 23 | { 24 | return NodeDataType{ "decimal", 25 | QStringLiteral("浮点数") }; 26 | } 27 | 28 | double number() const 29 | { 30 | return _number; 31 | } 32 | 33 | QString numberAsText() const 34 | { 35 | return QString::number(_number, 'f'); 36 | } 37 | 38 | private: 39 | 40 | double _number; 41 | }; 42 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/DivisionModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "NodeDataModel.hpp" 7 | 8 | #include "MathOperationDataModel.hpp" 9 | 10 | #include "DecimalData.hpp" 11 | 12 | /// The model dictates the number of inputs and outputs for the Node. 13 | /// In this example it has no logic. 14 | class DivisionModel : public MathOperationDataModel 15 | { 16 | public: 17 | 18 | virtual 19 | ~DivisionModel() {} 20 | 21 | public: 22 | QString 23 | caption() const override 24 | { 25 | return QStringLiteral("除法"); 26 | } 27 | 28 | bool 29 | portCaptionVisible(PortType portType, PortIndex portIndex) const override 30 | { 31 | Q_UNUSED(portType); Q_UNUSED(portIndex); 32 | return true; 33 | } 34 | 35 | QString 36 | portCaption(PortType portType, PortIndex portIndex) const override 37 | { 38 | switch (portType) 39 | { 40 | case PortType::In: 41 | if (portIndex == 0) 42 | return QStringLiteral("除数"); 43 | else if (portIndex == 1) 44 | return QStringLiteral("被除数"); 45 | 46 | break; 47 | 48 | case PortType::Out: 49 | return QStringLiteral("结果"); 50 | 51 | default: 52 | break; 53 | } 54 | return QString(); 55 | } 56 | 57 | QString 58 | name() const override 59 | { 60 | return QStringLiteral("除法"); 61 | } 62 | 63 | private: 64 | 65 | void 66 | compute() override 67 | { 68 | PortIndex const outPortIndex = 0; 69 | 70 | auto n1 = _number1.lock(); 71 | auto n2 = _number2.lock(); 72 | 73 | if (n2 && (n2->number() == 0.0)) 74 | { 75 | modelValidationState = NodeValidationState::Error; 76 | modelValidationError = QStringLiteral("被除数无法为0!"); 77 | _result.reset(); 78 | } 79 | else if (n1 && n2) 80 | { 81 | modelValidationState = NodeValidationState::Valid; 82 | modelValidationError = QString(); 83 | _result = std::make_shared(n1->number() / 84 | n2->number()); 85 | } 86 | else 87 | { 88 | modelValidationState = NodeValidationState::Warning; 89 | modelValidationError = QStringLiteral("未连接或运行失败!"); 90 | _result.reset(); 91 | } 92 | 93 | Q_EMIT dataUpdated(outPortIndex); 94 | } 95 | }; 96 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/IntegerData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NodeDataModel.hpp" 4 | 5 | using QtNodes::NodeDataType; 6 | using QtNodes::NodeData; 7 | 8 | /// The class can potentially incapsulate any user data which 9 | /// need to be transferred within the Node Editor graph 10 | class IntegerData : public NodeData 11 | { 12 | public: 13 | 14 | IntegerData() 15 | : _number(0.0) 16 | {} 17 | 18 | IntegerData(int const number) 19 | : _number(number) 20 | {} 21 | 22 | NodeDataType type() const override 23 | { 24 | return NodeDataType{ "integer", 25 | QStringLiteral("整数") }; 26 | } 27 | 28 | int number() const 29 | { 30 | return _number; 31 | } 32 | 33 | QString numberAsText() const 34 | { 35 | return QString::number(_number); 36 | } 37 | 38 | private: 39 | 40 | int _number; 41 | }; 42 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/MathNodes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //math nodes 4 | #include "calculator/AdditionModel.hpp" 5 | #include "calculator/DivisionModel.hpp" 6 | #include "calculator/MultiplicationModel.hpp" 7 | #include "calculator/SubtractionModel.hpp" 8 | #include "calculator/NumberSourceDataModel.hpp" 9 | #include "calculator/NumberDisplayDataModel.hpp" 10 | 11 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/MathOperationDataModel.cpp: -------------------------------------------------------------------------------- 1 | #include "MathOperationDataModel.hpp" 2 | 3 | #include "DecimalData.hpp" 4 | 5 | unsigned int 6 | MathOperationDataModel:: 7 | nPorts(PortType portType) const 8 | { 9 | unsigned int result; 10 | 11 | if (portType == PortType::In) 12 | result = 2; 13 | else 14 | result = 1; 15 | 16 | return result; 17 | } 18 | 19 | 20 | NodeDataType 21 | MathOperationDataModel:: 22 | dataType(PortType, PortIndex) const 23 | { 24 | return DecimalData().type(); 25 | } 26 | 27 | 28 | std::shared_ptr 29 | MathOperationDataModel:: 30 | outData(PortIndex) 31 | { 32 | return std::static_pointer_cast(_result); 33 | } 34 | 35 | 36 | void 37 | MathOperationDataModel:: 38 | setInData(std::shared_ptr data, PortIndex portIndex) 39 | { 40 | auto numberData = 41 | std::dynamic_pointer_cast(data); 42 | 43 | if (portIndex == 0) 44 | { 45 | _number1 = numberData; 46 | } 47 | else 48 | { 49 | _number2 = numberData; 50 | } 51 | compute(); 52 | } 53 | 54 | NodeValidationState 55 | MathOperationDataModel:: 56 | validationState() const 57 | { 58 | return modelValidationState; 59 | } 60 | 61 | 62 | QString 63 | MathOperationDataModel:: 64 | validationMessage() const 65 | { 66 | return modelValidationError; 67 | } 68 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/MathOperationDataModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "NodeDataModel.hpp" 8 | 9 | #include 10 | 11 | class DecimalData; 12 | 13 | using QtNodes::PortType; 14 | using QtNodes::PortIndex; 15 | using QtNodes::NodeData; 16 | using QtNodes::NodeDataType; 17 | using QtNodes::NodeDataModel; 18 | using QtNodes::NodeValidationState; 19 | 20 | /// The model dictates the number of inputs and outputs for the Node. 21 | /// In this example it has no logic. 22 | class MathOperationDataModel : public NodeDataModel 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | 28 | virtual 29 | ~MathOperationDataModel() {} 30 | 31 | public: 32 | 33 | unsigned int 34 | nPorts(PortType portType) const override; 35 | 36 | NodeDataType 37 | dataType(PortType portType, 38 | PortIndex portIndex) const override; 39 | 40 | std::shared_ptr 41 | outData(PortIndex port) override; 42 | 43 | void 44 | setInData(std::shared_ptr data, PortIndex portIndex) override; 45 | 46 | QWidget* 47 | embeddedWidget() override { return nullptr; } 48 | 49 | NodeValidationState 50 | validationState() const override; 51 | 52 | QString 53 | validationMessage() const override; 54 | 55 | protected: 56 | 57 | virtual void 58 | compute() = 0; 59 | 60 | protected: 61 | 62 | std::weak_ptr _number1; 63 | std::weak_ptr _number2; 64 | 65 | std::shared_ptr _result; 66 | 67 | NodeValidationState modelValidationState = NodeValidationState::Warning; 68 | QString modelValidationError = QStringLiteral("未连接或运行失败!"); 69 | }; 70 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/ModuloModel.cpp: -------------------------------------------------------------------------------- 1 | #include "ModuloModel.hpp" 2 | 3 | #include 4 | 5 | #include "IntegerData.hpp" 6 | 7 | QJsonObject 8 | ModuloModel:: 9 | save() const 10 | { 11 | QJsonObject modelJson; 12 | 13 | modelJson["name"] = name(); 14 | 15 | return modelJson; 16 | } 17 | 18 | 19 | unsigned int 20 | ModuloModel:: 21 | nPorts(PortType portType) const 22 | { 23 | unsigned int result = 1; 24 | 25 | switch (portType) 26 | { 27 | case PortType::In: 28 | result = 2; 29 | break; 30 | 31 | case PortType::Out: 32 | result = 1; 33 | 34 | default: 35 | break; 36 | } 37 | 38 | return result; 39 | } 40 | 41 | 42 | NodeDataType 43 | ModuloModel:: 44 | dataType(PortType, PortIndex) const 45 | { 46 | return IntegerData().type(); 47 | } 48 | 49 | 50 | std::shared_ptr 51 | ModuloModel:: 52 | outData(PortIndex) 53 | { 54 | return _result; 55 | } 56 | 57 | 58 | void 59 | ModuloModel:: 60 | setInData(std::shared_ptr data, PortIndex portIndex) 61 | { 62 | auto numberData = 63 | std::dynamic_pointer_cast(data); 64 | 65 | if (portIndex == 0) 66 | { 67 | _number1 = numberData; 68 | } 69 | else 70 | { 71 | _number2 = numberData; 72 | } 73 | 74 | { 75 | PortIndex const outPortIndex = 0; 76 | 77 | auto n1 = _number1.lock(); 78 | auto n2 = _number2.lock(); 79 | 80 | if (n2 && (n2->number() == 0.0)) 81 | { 82 | modelValidationState = NodeValidationState::Error; 83 | modelValidationError = QStringLiteral("Division by zero error"); 84 | _result.reset(); 85 | } 86 | else if (n1 && n2) 87 | { 88 | modelValidationState = NodeValidationState::Valid; 89 | modelValidationError = QString(); 90 | _result = std::make_shared(n1->number() % 91 | n2->number()); 92 | } 93 | else 94 | { 95 | modelValidationState = NodeValidationState::Warning; 96 | modelValidationError = QStringLiteral("Missing or incorrect inputs"); 97 | _result.reset(); 98 | } 99 | 100 | Q_EMIT dataUpdated(outPortIndex); 101 | } 102 | } 103 | 104 | 105 | NodeValidationState 106 | ModuloModel:: 107 | validationState() const 108 | { 109 | return modelValidationState; 110 | } 111 | 112 | 113 | QString 114 | ModuloModel:: 115 | validationMessage() const 116 | { 117 | return modelValidationError; 118 | } 119 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/ModuloModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "NodeDataModel.hpp" 7 | 8 | #include 9 | 10 | using QtNodes::PortType; 11 | using QtNodes::PortIndex; 12 | using QtNodes::NodeData; 13 | using QtNodes::NodeDataType; 14 | using QtNodes::NodeDataModel; 15 | using QtNodes::NodeValidationState; 16 | 17 | class IntegerData; 18 | 19 | class ModuloModel 20 | : public NodeDataModel 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | ModuloModel() = default; 26 | 27 | virtual 28 | ~ModuloModel() = default; 29 | 30 | public: 31 | 32 | QString 33 | caption() const override 34 | { 35 | return QStringLiteral("求模"); 36 | } 37 | 38 | bool 39 | captionVisible() const override 40 | { 41 | return true; 42 | } 43 | 44 | bool 45 | portCaptionVisible(PortType, PortIndex) const override 46 | { 47 | return true; 48 | } 49 | 50 | QString 51 | portCaption(PortType portType, PortIndex portIndex) const override 52 | { 53 | switch (portType) 54 | { 55 | case PortType::In: 56 | if (portIndex == 0) 57 | return QStringLiteral("求模数"); 58 | else if (portIndex == 1) 59 | return QStringLiteral("被模数"); 60 | 61 | break; 62 | 63 | case PortType::Out: 64 | return QStringLiteral("结果"); 65 | 66 | default: 67 | break; 68 | } 69 | return QString(); 70 | } 71 | 72 | QString 73 | name() const override 74 | { 75 | return QStringLiteral("求模"); 76 | } 77 | 78 | public: 79 | 80 | QJsonObject 81 | save() const override; 82 | 83 | public: 84 | 85 | unsigned int 86 | nPorts(PortType portType) const override; 87 | 88 | NodeDataType 89 | dataType(PortType portType, PortIndex portIndex) const override; 90 | 91 | std::shared_ptr 92 | outData(PortIndex port) override; 93 | 94 | void 95 | setInData(std::shared_ptr, int) override; 96 | 97 | QWidget* 98 | embeddedWidget() override { return nullptr; } 99 | 100 | NodeValidationState 101 | validationState() const override; 102 | 103 | QString 104 | validationMessage() const override; 105 | 106 | private: 107 | 108 | std::weak_ptr _number1; 109 | std::weak_ptr _number2; 110 | 111 | std::shared_ptr _result; 112 | 113 | NodeValidationState modelValidationState = NodeValidationState::Warning; 114 | QString modelValidationError = QStringLiteral("未连接或运行失败!"); 115 | }; 116 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/MultiplicationModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "NodeDataModel.hpp" 7 | 8 | #include "MathOperationDataModel.hpp" 9 | 10 | #include "DecimalData.hpp" 11 | 12 | /// The model dictates the number of inputs and outputs for the Node. 13 | /// In this example it has no logic. 14 | class MultiplicationModel : public MathOperationDataModel 15 | { 16 | public: 17 | 18 | virtual 19 | ~MultiplicationModel() {} 20 | 21 | public: 22 | 23 | QString 24 | caption() const override 25 | { 26 | return QStringLiteral("乘法"); 27 | } 28 | 29 | QString 30 | name() const override 31 | { 32 | return QStringLiteral("乘法"); 33 | } 34 | 35 | private: 36 | 37 | void 38 | compute() override 39 | { 40 | PortIndex const outPortIndex = 0; 41 | 42 | auto n1 = _number1.lock(); 43 | auto n2 = _number2.lock(); 44 | 45 | if (n1 && n2) 46 | { 47 | modelValidationState = NodeValidationState::Valid; 48 | modelValidationError = QString(); 49 | _result = std::make_shared(n1->number() * 50 | n2->number()); 51 | } 52 | else 53 | { 54 | modelValidationState = NodeValidationState::Warning; 55 | modelValidationError = QStringLiteral("未连接或输入错误!"); 56 | _result.reset(); 57 | } 58 | 59 | Q_EMIT dataUpdated(outPortIndex); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/NumberDisplayDataModel.cpp: -------------------------------------------------------------------------------- 1 | #include "NumberDisplayDataModel.hpp" 2 | 3 | #include "DecimalData.hpp" 4 | 5 | #include 6 | 7 | NumberDisplayDataModel:: 8 | NumberDisplayDataModel() 9 | : _label{nullptr} 10 | { 11 | } 12 | 13 | 14 | unsigned int 15 | NumberDisplayDataModel:: 16 | nPorts(PortType portType) const 17 | { 18 | unsigned int result = 1; 19 | 20 | switch (portType) 21 | { 22 | case PortType::In: 23 | result = 1; 24 | break; 25 | 26 | case PortType::Out: 27 | result = 0; 28 | 29 | default: 30 | break; 31 | } 32 | 33 | return result; 34 | } 35 | 36 | 37 | NodeDataType 38 | NumberDisplayDataModel:: 39 | dataType(PortType, PortIndex) const 40 | { 41 | return DecimalData().type(); 42 | } 43 | 44 | 45 | std::shared_ptr 46 | NumberDisplayDataModel:: 47 | outData(PortIndex) 48 | { 49 | std::shared_ptr ptr; 50 | return ptr; 51 | } 52 | 53 | 54 | void 55 | NumberDisplayDataModel:: 56 | setInData(std::shared_ptr data, int) 57 | { 58 | auto numberData = std::dynamic_pointer_cast(data); 59 | 60 | if (numberData) 61 | { 62 | modelValidationState = NodeValidationState::Valid; 63 | modelValidationError = QString(); 64 | _label->setText(numberData->numberAsText()); 65 | } 66 | else 67 | { 68 | modelValidationState = NodeValidationState::Warning; 69 | modelValidationError = QStringLiteral("Missing or incorrect inputs"); 70 | _label->clear(); 71 | } 72 | 73 | _label->adjustSize(); 74 | } 75 | 76 | QWidget* 77 | NumberDisplayDataModel:: 78 | embeddedWidget() 79 | { 80 | if (!_label) 81 | { 82 | _label = new QLabel(); 83 | _label->setMargin(3); 84 | } 85 | 86 | return _label; 87 | } 88 | 89 | NodeValidationState 90 | NumberDisplayDataModel:: 91 | validationState() const 92 | { 93 | return modelValidationState; 94 | } 95 | 96 | 97 | QString 98 | NumberDisplayDataModel:: 99 | validationMessage() const 100 | { 101 | return modelValidationError; 102 | } 103 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/NumberDisplayDataModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "NodeDataModel.hpp" 6 | 7 | #include 8 | 9 | using QtNodes::PortType; 10 | using QtNodes::PortIndex; 11 | using QtNodes::NodeData; 12 | using QtNodes::NodeDataType; 13 | using QtNodes::NodeDataModel; 14 | using QtNodes::NodeValidationState; 15 | 16 | class QLabel; 17 | 18 | /// The model dictates the number of inputs and outputs for the Node. 19 | /// In this example it has no logic. 20 | class NumberDisplayDataModel : public NodeDataModel 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | NumberDisplayDataModel(); 26 | 27 | virtual 28 | ~NumberDisplayDataModel() {} 29 | 30 | public: 31 | 32 | QString 33 | caption() const override 34 | { 35 | return QStringLiteral("数字显示"); 36 | } 37 | 38 | bool 39 | captionVisible() const override 40 | { 41 | return true; 42 | } 43 | 44 | QString 45 | name() const override 46 | { 47 | return QStringLiteral("数字显示"); 48 | } 49 | 50 | public: 51 | 52 | unsigned int 53 | nPorts(PortType portType) const override; 54 | 55 | NodeDataType 56 | dataType(PortType portType, 57 | PortIndex portIndex) const override; 58 | 59 | std::shared_ptr 60 | outData(PortIndex port) override; 61 | 62 | void 63 | setInData(std::shared_ptr data, int) override; 64 | 65 | QWidget* 66 | embeddedWidget() override; 67 | 68 | NodeValidationState 69 | validationState() const override; 70 | 71 | QString 72 | validationMessage() const override; 73 | 74 | private: 75 | 76 | NodeValidationState modelValidationState = NodeValidationState::Warning; 77 | QString modelValidationError = QStringLiteral("未连接或运算失败!"); 78 | 79 | QLabel* _label; 80 | }; 81 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/NumberSourceDataModel.cpp: -------------------------------------------------------------------------------- 1 | #include "NumberSourceDataModel.hpp" 2 | 3 | #include "DecimalData.hpp" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | NumberSourceDataModel:: 10 | NumberSourceDataModel() 11 | : _lineEdit{ nullptr } 12 | { 13 | } 14 | 15 | 16 | QJsonObject 17 | NumberSourceDataModel:: 18 | save() const 19 | { 20 | QJsonObject modelJson = NodeDataModel::save(); 21 | 22 | if (_number) 23 | modelJson["number"] = QString::number(_number->number()); 24 | 25 | return modelJson; 26 | } 27 | 28 | 29 | void 30 | NumberSourceDataModel:: 31 | restore(QJsonObject const& p) 32 | { 33 | QJsonValue v = p["number"]; 34 | 35 | if (!v.isUndefined()) 36 | { 37 | QString strNum = v.toString(); 38 | 39 | bool ok; 40 | double d = strNum.toDouble(&ok); 41 | if (ok) 42 | { 43 | _number = std::make_shared(d); 44 | _lineEdit->setText(strNum); 45 | } 46 | } 47 | } 48 | 49 | unsigned int 50 | NumberSourceDataModel:: 51 | nPorts(PortType portType) const 52 | { 53 | unsigned int result = 1; 54 | 55 | switch (portType) 56 | { 57 | case PortType::In: 58 | result = 0; 59 | break; 60 | 61 | case PortType::Out: 62 | result = 1; 63 | 64 | default: 65 | break; 66 | } 67 | 68 | return result; 69 | } 70 | 71 | 72 | void 73 | NumberSourceDataModel:: 74 | onTextEdited(QString const& string) 75 | { 76 | Q_UNUSED(string); 77 | 78 | bool ok = false; 79 | 80 | double number = _lineEdit->text().toDouble(&ok); 81 | 82 | if (ok) 83 | { 84 | _number = std::make_shared(number); 85 | 86 | Q_EMIT dataUpdated(0); 87 | } 88 | else 89 | { 90 | Q_EMIT dataInvalidated(0); 91 | } 92 | } 93 | 94 | 95 | NodeDataType 96 | NumberSourceDataModel:: 97 | dataType(PortType, PortIndex) const 98 | { 99 | return DecimalData().type(); 100 | } 101 | 102 | 103 | std::shared_ptr 104 | NumberSourceDataModel:: 105 | outData(PortIndex) 106 | { 107 | return _number; 108 | } 109 | 110 | 111 | QWidget* 112 | NumberSourceDataModel:: 113 | embeddedWidget() 114 | { 115 | if (!_lineEdit) 116 | { 117 | _lineEdit = new QLineEdit(); 118 | 119 | _lineEdit->setValidator(new QDoubleValidator()); 120 | _lineEdit->setMaximumSize(_lineEdit->sizeHint()); 121 | 122 | connect(_lineEdit, &QLineEdit::textChanged, 123 | this, &NumberSourceDataModel::onTextEdited); 124 | 125 | _lineEdit->setText("0.0"); 126 | } 127 | 128 | return _lineEdit; 129 | } 130 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/NumberSourceDataModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "NodeDataModel.hpp" 6 | 7 | #include 8 | 9 | class DecimalData; 10 | 11 | using QtNodes::PortType; 12 | using QtNodes::PortIndex; 13 | using QtNodes::NodeData; 14 | using QtNodes::NodeDataType; 15 | using QtNodes::NodeDataModel; 16 | using QtNodes::NodeValidationState; 17 | 18 | class QLineEdit; 19 | 20 | /// The model dictates the number of inputs and outputs for the Node. 21 | /// In this example it has no logic. 22 | class NumberSourceDataModel 23 | : public NodeDataModel 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | NumberSourceDataModel(); 29 | 30 | virtual 31 | ~NumberSourceDataModel() {} 32 | 33 | public: 34 | 35 | QString 36 | caption() const override 37 | { 38 | return QStringLiteral("数字输入"); 39 | } 40 | 41 | bool 42 | captionVisible() const override 43 | { 44 | return true; 45 | } 46 | 47 | QString 48 | name() const override 49 | { 50 | return QStringLiteral("数字输入"); 51 | } 52 | 53 | public: 54 | 55 | QJsonObject 56 | save() const override; 57 | 58 | void 59 | restore(QJsonObject const& p) override; 60 | 61 | public: 62 | 63 | unsigned int 64 | nPorts(PortType portType) const override; 65 | 66 | NodeDataType 67 | dataType(PortType portType, PortIndex portIndex) const override; 68 | 69 | std::shared_ptr 70 | outData(PortIndex port) override; 71 | 72 | void 73 | setInData(std::shared_ptr, int) override 74 | { } 75 | 76 | QWidget* 77 | embeddedWidget() override; 78 | 79 | private Q_SLOTS: 80 | 81 | void 82 | onTextEdited(QString const& string); 83 | 84 | private: 85 | 86 | std::shared_ptr _number; 87 | 88 | QLineEdit* _lineEdit; 89 | }; 90 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/calculator/SubtractionModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "NodeDataModel.hpp" 7 | 8 | #include "MathOperationDataModel.hpp" 9 | 10 | #include "DecimalData.hpp" 11 | 12 | /// The model dictates the number of inputs and outputs for the Node. 13 | /// In this example it has no logic. 14 | class SubtractionModel : public MathOperationDataModel 15 | { 16 | public: 17 | 18 | virtual 19 | ~SubtractionModel() {} 20 | 21 | public: 22 | 23 | QString 24 | caption() const override 25 | { 26 | return QStringLiteral("减法节点"); 27 | } 28 | 29 | virtual bool 30 | portCaptionVisible(PortType portType, PortIndex portIndex) const override 31 | { 32 | Q_UNUSED(portType); Q_UNUSED(portIndex); 33 | return true; 34 | } 35 | 36 | virtual QString 37 | portCaption(PortType portType, PortIndex portIndex) const override 38 | { 39 | switch (portType) 40 | { 41 | case PortType::In: 42 | if (portIndex == 0) 43 | return QStringLiteral("减数"); 44 | else if (portIndex == 1) 45 | return QStringLiteral("被减数"); 46 | 47 | break; 48 | 49 | case PortType::Out: 50 | return QStringLiteral("结果"); 51 | 52 | default: 53 | break; 54 | } 55 | return QString(); 56 | } 57 | 58 | QString 59 | name() const override 60 | { 61 | return QStringLiteral("减法"); 62 | } 63 | 64 | private: 65 | 66 | void 67 | compute() override 68 | { 69 | PortIndex const outPortIndex = 0; 70 | 71 | auto n1 = _number1.lock(); 72 | auto n2 = _number2.lock(); 73 | 74 | if (n1 && n2) 75 | { 76 | modelValidationState = NodeValidationState::Valid; 77 | modelValidationError = QString(); 78 | _result = std::make_shared(n1->number() - 79 | n2->number()); 80 | } 81 | else 82 | { 83 | modelValidationState = NodeValidationState::Warning; 84 | modelValidationError = QStringLiteral("缺失节点或运行失败!"); 85 | _result.reset(); 86 | } 87 | 88 | Q_EMIT dataUpdated(outPortIndex); 89 | } 90 | }; 91 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageDLSegmentModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HImageDLSegmentModel.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "HRegionData.hpp" 9 | #include "DrawShapeView.hpp" 10 | #include "halconcpp/HalconCpp.h" 11 | #include "QJsonParser.hpp" 12 | using namespace HalconCpp; 13 | 14 | 15 | HImageDLSegmentModel::HImageDLSegmentModel() 16 | { 17 | m_hImage = std::make_shared(); 18 | m_result = std::make_shared(); 19 | btn_select_model = new QPushButton(QStringLiteral("选择模型")); 20 | 21 | connect(DrawShapeView::getInst(), SIGNAL(RegionFinished(RegionPixmapData)), 22 | this, SLOT(OnNewRegionData(RegionPixmapData))); 23 | 24 | connect(btn_select_model, &QPushButton::clicked, [=]() 25 | { 26 | dl_path.clear(); 27 | dl_path = 28 | QFileDialog::getOpenFileName(nullptr, 29 | tr("Select Dl Model"), 30 | QDir::homePath(), 31 | tr("File (*.hdl)")); 32 | if (dl_path == "") 33 | { 34 | return; 35 | } 36 | readDlModel(dl_path); 37 | }); 38 | } 39 | 40 | bool HImageDLSegmentModel::RunTask() 41 | { 42 | PortIndex const outPortIndex = 0; 43 | try 44 | { 45 | 46 | modelValidationState = NodeValidationState::Valid; 47 | modelValidationError = QString(); 48 | } 49 | catch (...) 50 | { 51 | modelValidationState = NodeValidationState::Warning; 52 | modelValidationError = QStringLiteral("缺失或运行失败!"); 53 | } 54 | 55 | return true; 56 | } 57 | 58 | void HImageDLSegmentModel::OnNewRegionData(ShapeDataStruct _data) 59 | { 60 | //if (!DrawShapeView::getInst()->getDrawFlag()) 61 | //{ 62 | // return; 63 | //} 64 | RunTask(); 65 | } 66 | 67 | unsigned int HImageDLSegmentModel:: 68 | nPorts(PortType portType) const 69 | { 70 | unsigned int result = 1; 71 | 72 | switch (portType) 73 | { 74 | case PortType::In: 75 | result = 1; 76 | break; 77 | case PortType::Out: 78 | result = 1; 79 | default: 80 | break; 81 | } 82 | 83 | return result; 84 | } 85 | 86 | NodeValidationState HImageDLSegmentModel::validationState() const 87 | { 88 | return modelValidationState; 89 | } 90 | 91 | QString HImageDLSegmentModel::validationMessage() const 92 | { 93 | return modelValidationError; 94 | } 95 | 96 | QJsonObject HImageDLSegmentModel::save() const 97 | { 98 | QJsonObject result = NodeDataModel::save(); 99 | result.insert("dl_path", dl_path); 100 | return result; 101 | } 102 | 103 | void HImageDLSegmentModel::restore(QJsonObject const& _json) 104 | { 105 | dl_path = _json.value("dl_path").toString(); 106 | } 107 | 108 | void HImageDLSegmentModel::readDlModel(QString modelFileName) 109 | { 110 | m_dl_model = new HDlModel(); 111 | m_dl_model->ReadDlModel(modelFileName.toStdString().c_str()); 112 | image_dimensions = m_dl_model->GetDlModelParam("image_dimensions"); 113 | class_ids = m_dl_model->GetDlModelParam("class_ids"); 114 | m_dl_model->SetDlModelParam("batch_size", 1); 115 | } 116 | 117 | NodeDataType 118 | HImageDLSegmentModel::dataType(PortType port_type, PortIndex port_index) const 119 | { 120 | if (port_type == PortType::In) 121 | { 122 | switch (port_index) 123 | { 124 | case 0: 125 | return HImageData().type(); 126 | break; 127 | } 128 | } 129 | else 130 | { 131 | switch (port_index) 132 | { 133 | case 0: 134 | return HRegionData().type(); 135 | break; 136 | } 137 | } 138 | return HImageData().type(); 139 | } 140 | 141 | void HImageDLSegmentModel:: 142 | setInData(std::shared_ptr data, int portIndex) 143 | { 144 | auto hImageData = 145 | std::dynamic_pointer_cast(data); 146 | if (hImageData == nullptr) 147 | { 148 | return; 149 | } 150 | switch (portIndex) 151 | { 152 | case 0: 153 | m_hImage->setHImage(*hImageData->hImage()); 154 | break; 155 | default: 156 | break; 157 | } 158 | RunTask(); 159 | } 160 | 161 | std::shared_ptr 162 | HImageDLSegmentModel:: 163 | outData(PortIndex) 164 | { 165 | return std::dynamic_pointer_cast(m_result); 166 | } 167 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageDLSegmentModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "DataModelRegistry.hpp" 9 | #include "NodeDataModel.hpp" 10 | #include "halconcpp/HalconCpp.h" 11 | #include "HImageData.hpp" 12 | #include "HRegionData.hpp" 13 | #include "HImageViewWidget.hpp" 14 | #include "DrawShapeView.hpp" 15 | 16 | using QtNodes::PortType; 17 | using QtNodes::PortIndex; 18 | using QtNodes::NodeData; 19 | using QtNodes::NodeDataType; 20 | using QtNodes::NodeDataModel; 21 | using QtNodes::NodeValidationState; 22 | using namespace HalconCpp; 23 | /** 24 | * \brief halcon 图像rgb2gray节点 25 | */ 26 | class HImageDLSegmentModel :public NodeDataModel 27 | { 28 | Q_OBJECT 29 | public: 30 | HImageDLSegmentModel(); 31 | virtual ~HImageDLSegmentModel() {} 32 | 33 | public: 34 | QString caption() const override 35 | { 36 | return QStringLiteral("语义分割"); 37 | } 38 | QString name() const override 39 | { 40 | return QStringLiteral("语义分割"); 41 | } 42 | virtual QString modelName() const 43 | { 44 | return QStringLiteral("语义分割"); 45 | } 46 | unsigned int 47 | nPorts(PortType portType) const override; 48 | 49 | NodeDataType 50 | dataType(PortType portType, PortIndex portIndex) const override; 51 | 52 | std::shared_ptr 53 | outData(PortIndex port) override; 54 | 55 | void 56 | setInData(std::shared_ptr, int) override; 57 | 58 | QWidget* 59 | embeddedWidget() override { return btn_select_model; } 60 | 61 | bool 62 | resizable() const override { return false; } 63 | NodeValidationState 64 | validationState() const override; 65 | QString 66 | validationMessage() const override; 67 | QJsonObject save() const override; 68 | void restore(QJsonObject const&) override; 69 | void readDlModel(QString modelFileName); 70 | protected: 71 | bool RunTask(); 72 | 73 | public slots: 74 | void OnNewRegionData(ShapeDataStruct _data); 75 | public: 76 | NodeValidationState modelValidationState = NodeValidationState::Warning; 77 | QString modelValidationError = QStringLiteral("图片输入未连接!"); 78 | private: 79 | QString dl_path; 80 | QPushButton* btn_select_model; 81 | HDlModel* m_dl_model; 82 | HTuple image_dimensions; 83 | HTuple class_ids; 84 | HTuple valid_thres = 0.7; 85 | std::shared_ptr m_hImage; 86 | std::shared_ptr m_result; 87 | }; 88 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "NodeDataModel.hpp" 6 | #include "halconcpp/HalconCpp.h" 7 | 8 | using QtNodes::NodeData; 9 | using QtNodes::NodeDataType; 10 | using namespace HalconCpp; 11 | 12 | class HImageData :public NodeData 13 | { 14 | public: 15 | HImageData() 16 | { 17 | m_himage = HImage(); 18 | } 19 | HImageData(HImage& h_image) 20 | { 21 | if (h_image.IsInitialized()) 22 | { 23 | m_himage = h_image; 24 | } 25 | } 26 | virtual ~HImageData() 27 | { 28 | 29 | } 30 | NodeDataType type() const override 31 | { 32 | return { "HImage","Img" }; 33 | } 34 | HImage* hImage() { return &m_himage; } 35 | void setHImage(HImage const& _img) 36 | { 37 | if (!_img.IsInitialized()) 38 | { 39 | return; 40 | } 41 | m_himage = _img; 42 | } 43 | private: 44 | HImage m_himage; 45 | }; 46 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageFolderModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "DataModelRegistry.hpp" 11 | #include "NodeDataModel.hpp" 12 | #include "halconcpp/HalconCpp.h" 13 | #include "HImageData.hpp" 14 | #include "HImageViewWidget.hpp" 15 | 16 | using QtNodes::PortType; 17 | using QtNodes::PortIndex; 18 | using QtNodes::NodeData; 19 | using QtNodes::NodeDataType; 20 | using QtNodes::NodeDataModel; 21 | using QtNodes::NodeValidationState; 22 | using namespace HalconCpp; 23 | /** 24 | * \brief halcon 图像输入节点 25 | */ 26 | class HImageFolderModel :public NodeDataModel 27 | { 28 | Q_OBJECT 29 | public: 30 | HImageFolderModel(); 31 | virtual ~HImageFolderModel() {} 32 | public: 33 | QString caption() const override 34 | { 35 | return QStringLiteral("图像目录输入"); 36 | } 37 | QString name() const override 38 | { 39 | return QStringLiteral("图像目录输入"); 40 | } 41 | virtual QString modelName() const 42 | { 43 | return QStringLiteral("图像目录输入"); 44 | } 45 | unsigned int 46 | nPorts(PortType portType) const override; 47 | 48 | NodeDataType 49 | dataType(PortType portType, PortIndex portIndex) const override; 50 | 51 | std::shared_ptr 52 | outData(PortIndex port) override; 53 | 54 | void 55 | setInData(std::shared_ptr, int) override 56 | { } 57 | 58 | QWidget* 59 | embeddedWidget() override { return m_paraWidget; } 60 | 61 | bool 62 | resizable() const override { return false; } 63 | QJsonObject save() const override; 64 | void restore(QJsonObject const&) override; 65 | void loadImageFolder(QString path, int index = 0); 66 | protected: 67 | bool eventFilter(QObject* watched, QEvent* event) override; 68 | private: 69 | QString folderPath; 70 | std::shared_ptr< HImageData> m_hImageData; 71 | QWidget* m_paraWidget; 72 | QVBoxLayout* m_host; 73 | QHBoxLayout* m_h_host; 74 | QPushButton* btn_selectFolder; 75 | QPushButton* btn_last; 76 | QPushButton* btn_next; 77 | HImageViewWidget* m_image_view; 78 | HTuple fileListStr; 79 | HTuple imgListStr; 80 | HImage tmpImg; 81 | int curIndex = 0; 82 | int imageCounst = 0; 83 | }; 84 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageLoaderModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HImageLoaderModel.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | HImageLoaderModel::HImageLoaderModel() 7 | { 8 | m_image_view = new HImageViewWidget(); 9 | m_image_view->installEventFilter(this); 10 | m_image_view->resize(200, 200); 11 | m_hImageData = std::make_shared(); 12 | } 13 | 14 | unsigned int HImageLoaderModel::nPorts(PortType portType) const 15 | { 16 | unsigned int result = 1; 17 | 18 | switch (portType) 19 | { 20 | case PortType::In: 21 | result = 0; 22 | break; 23 | 24 | case PortType::Out: 25 | result = 1; 26 | 27 | default: 28 | break; 29 | } 30 | 31 | return result; 32 | } 33 | 34 | QJsonObject HImageLoaderModel::save() const 35 | { 36 | QJsonObject modelJson = NodeDataModel::save(); 37 | if (m_hImageData) 38 | { 39 | HTuple* R, * G, * B; 40 | HTuple width, height; 41 | int chanels = m_hImageData->hImage()->CountChannels(); 42 | m_hImageData->hImage()->GetImageSize(&width, &height); 43 | modelJson.insert("width", width.D()); 44 | modelJson.insert("height", height.D()); 45 | modelJson.insert("chanels", chanels); 46 | modelJson.insert("imageName", imageName); 47 | } 48 | 49 | return modelJson; 50 | } 51 | 52 | void HImageLoaderModel::restore(QJsonObject const& p) 53 | { 54 | imageName = p["imageName"].toString(); 55 | loadImage(imageName); 56 | } 57 | 58 | void HImageLoaderModel::loadImage(QString fileName) 59 | { 60 | if (fileName == "") 61 | { 62 | return; 63 | } 64 | HImage tmpImg; 65 | tmpImg.ReadImage(fileName.toStdString().c_str()); 66 | m_hImageData->setHImage(tmpImg); 67 | m_image_view->showImage(*m_hImageData->hImage()); 68 | } 69 | 70 | bool HImageLoaderModel::eventFilter(QObject* object, QEvent* event) 71 | { 72 | if (object == m_image_view) 73 | { 74 | if (event->type() == QEvent::MouseButtonPress) 75 | { 76 | imageName = 77 | QFileDialog::getOpenFileName(nullptr, 78 | tr("Open Image"), 79 | QDir::homePath(), 80 | tr("Image Files (*.png *.jpg *.bmp)")); 81 | if (imageName == "") 82 | { 83 | return false; 84 | } 85 | 86 | loadImage(imageName); 87 | 88 | Q_EMIT dataUpdated(0); 89 | 90 | return true; 91 | } 92 | else if (event->type() == QEvent::Resize) 93 | { 94 | 95 | } 96 | } 97 | 98 | return false; 99 | } 100 | 101 | NodeDataType 102 | HImageLoaderModel::dataType(PortType, PortIndex) const 103 | { 104 | return HImageData().type(); 105 | } 106 | std::shared_ptr 107 | HImageLoaderModel:: 108 | outData(PortIndex) 109 | { 110 | return std::dynamic_pointer_cast(m_hImageData); 111 | } 112 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageLoaderModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "DataModelRegistry.hpp" 8 | #include "NodeDataModel.hpp" 9 | #include "halconcpp/HalconCpp.h" 10 | #include "HImageData.hpp" 11 | #include "HImageViewWidget.hpp" 12 | 13 | using QtNodes::PortType; 14 | using QtNodes::PortIndex; 15 | using QtNodes::NodeData; 16 | using QtNodes::NodeDataType; 17 | using QtNodes::NodeDataModel; 18 | using QtNodes::NodeValidationState; 19 | using namespace HalconCpp; 20 | /** 21 | * \brief halcon 图像输入节点 22 | */ 23 | class HImageLoaderModel :public NodeDataModel 24 | { 25 | Q_OBJECT 26 | public: 27 | HImageLoaderModel(); 28 | virtual ~HImageLoaderModel() {} 29 | public: 30 | QString caption() const override 31 | { 32 | return QStringLiteral("图像输入"); 33 | } 34 | QString name() const override 35 | { 36 | return QStringLiteral("图像输入"); 37 | } 38 | virtual QString modelName() const 39 | { 40 | return QStringLiteral("图像输入"); 41 | } 42 | unsigned int 43 | nPorts(PortType portType) const override; 44 | 45 | NodeDataType 46 | dataType(PortType portType, PortIndex portIndex) const override; 47 | 48 | std::shared_ptr 49 | outData(PortIndex port) override; 50 | 51 | void 52 | setInData(std::shared_ptr, int) override 53 | { } 54 | 55 | QWidget* 56 | embeddedWidget() override { return m_image_view; } 57 | 58 | bool 59 | resizable() const override { return false; } 60 | QJsonObject save() const override; 61 | void restore(QJsonObject const&) override; 62 | void loadImage(QString fileName); 63 | protected: 64 | bool eventFilter(QObject* watched, QEvent* event) override; 65 | private: 66 | QString imageName; 67 | std::shared_ptr< HImageData> m_hImageData; 68 | HImageViewWidget* m_image_view; 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageRGB2GrayModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HImageRGB2GrayModel.hpp" 2 | #include 3 | 4 | #include "halconcpp/HalconCpp.h" 5 | 6 | using namespace HalconCpp; 7 | 8 | HImageRGB2GrayModel::HImageRGB2GrayModel() 9 | { 10 | m_hImage = std::make_shared(); 11 | } 12 | 13 | bool HImageRGB2GrayModel::RunTask() 14 | { 15 | Q_EMIT computingStarted(); 16 | PortIndex const outPortIndex = 0; 17 | try 18 | { 19 | HTuple imgChanels = m_hImage->hImage()->CountChannels(); 20 | if (imgChanels == 3) 21 | { 22 | HImage tmp_img = m_hImage->hImage()->Rgb3ToGray(*m_hImage->hImage(), *m_hImage->hImage()); 23 | m_hImage->setHImage(tmp_img); 24 | tmp_img.Clear(); 25 | } 26 | modelValidationState = NodeValidationState::Valid; 27 | modelValidationError = QString(); 28 | } 29 | catch (...) 30 | { 31 | modelValidationState = NodeValidationState::Warning; 32 | modelValidationError = QStringLiteral("缺失或运行失败!"); 33 | } 34 | 35 | Q_EMIT dataUpdated(outPortIndex); 36 | Q_EMIT computingFinished(); 37 | return true; 38 | } 39 | 40 | unsigned int HImageRGB2GrayModel:: 41 | nPorts(PortType portType) const 42 | { 43 | unsigned int result = 1; 44 | 45 | switch (portType) 46 | { 47 | case PortType::In: 48 | result = 1; 49 | break; 50 | 51 | case PortType::Out: 52 | result = 1; 53 | 54 | default: 55 | break; 56 | } 57 | 58 | return result; 59 | } 60 | 61 | NodeValidationState HImageRGB2GrayModel::validationState() const 62 | { 63 | return modelValidationState; 64 | } 65 | 66 | QString HImageRGB2GrayModel::validationMessage() const 67 | { 68 | return modelValidationError; 69 | } 70 | 71 | NodeDataType 72 | HImageRGB2GrayModel::dataType(PortType, PortIndex) const 73 | { 74 | return HImageData().type(); 75 | } 76 | 77 | void HImageRGB2GrayModel:: 78 | setInData(std::shared_ptr data, int portIndex) 79 | { 80 | auto hImageData = 81 | std::dynamic_pointer_cast(data); 82 | if (hImageData == nullptr) 83 | { 84 | return; 85 | } 86 | switch (portIndex) 87 | { 88 | case 0: 89 | m_hImage->setHImage(*hImageData->hImage()); 90 | break; 91 | default: 92 | break; 93 | } 94 | RunTask(); 95 | } 96 | 97 | std::shared_ptr 98 | HImageRGB2GrayModel:: 99 | outData(PortIndex) 100 | { 101 | return std::dynamic_pointer_cast(m_hImage); 102 | } 103 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageRGB2GrayModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "DataModelRegistry.hpp" 8 | #include "NodeDataModel.hpp" 9 | #include "halconcpp/HalconCpp.h" 10 | #include "HImageData.hpp" 11 | #include "HImageViewWidget.hpp" 12 | 13 | using QtNodes::PortType; 14 | using QtNodes::PortIndex; 15 | using QtNodes::NodeData; 16 | using QtNodes::NodeDataType; 17 | using QtNodes::NodeDataModel; 18 | using QtNodes::NodeValidationState; 19 | using namespace HalconCpp; 20 | /** 21 | * \brief halcon 图像rgb2gray节点 22 | */ 23 | class HImageRGB2GrayModel :public NodeDataModel 24 | { 25 | Q_OBJECT 26 | public: 27 | HImageRGB2GrayModel(); 28 | virtual ~HImageRGB2GrayModel() {} 29 | 30 | public: 31 | QString caption() const override 32 | { 33 | return QStringLiteral("图像转灰度"); 34 | } 35 | QString name() const override 36 | { 37 | return QStringLiteral("图像转灰度"); 38 | } 39 | virtual QString modelName() const 40 | { 41 | return QStringLiteral("图像转灰度"); 42 | } 43 | unsigned int 44 | nPorts(PortType portType) const override; 45 | 46 | NodeDataType 47 | dataType(PortType portType, PortIndex portIndex) const override; 48 | 49 | std::shared_ptr 50 | outData(PortIndex port) override; 51 | 52 | void 53 | setInData(std::shared_ptr, int) override; 54 | 55 | QWidget* 56 | embeddedWidget() override { return Q_NULLPTR; } 57 | 58 | bool 59 | resizable() const override { return false; } 60 | NodeValidationState 61 | validationState() const override; 62 | QString 63 | validationMessage() const override; 64 | protected: 65 | bool RunTask(); 66 | 67 | public: 68 | NodeValidationState modelValidationState = NodeValidationState::Warning; 69 | QString modelValidationError = QStringLiteral("图片输入未连接!"); 70 | private: 71 | std::shared_ptr m_hImage; 72 | 73 | }; 74 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageReduceDomainModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HImageReduceDomainModel.hpp" 2 | 3 | #include 4 | #include 5 | #include "DrawShapeView.hpp" 6 | #include "halconcpp/HalconCpp.h" 7 | #include "QJsonParser.hpp" 8 | using namespace HalconCpp; 9 | 10 | 11 | HImageReduceDomainModel::HImageReduceDomainModel() 12 | { 13 | m_hImage = std::make_shared(); 14 | m_result = std::make_shared(); 15 | btn_drawReg = new QPushButton(QStringLiteral("绘制区域")); 16 | m_region_data = std::make_shared(); 17 | m_domain.GenEmptyRegion(); 18 | 19 | connect(DrawShapeView::getInst(), SIGNAL(RegionComform(ShapeDataStruct)), 20 | this, SLOT(OnNewRegionData(ShapeDataStruct))); 21 | 22 | connect(btn_drawReg, &QPushButton::clicked, [=]() 23 | { 24 | QPixmap tmpPix; 25 | HImageViewWidget::HImageToQPixmap(*m_hImage->hImage(), tmpPix); 26 | DrawShapeView::getInst()->FitShowImage(tmpPix, *m_region_data); 27 | }); 28 | } 29 | 30 | bool HImageReduceDomainModel::RunTask() 31 | { 32 | //Q_EMIT computingStarted(); 33 | PortIndex const outPortIndex = 0; 34 | try 35 | { 36 | if ((int)m_region_data->shapePolygon.size() > 0) 37 | { 38 | HImage tmpImage; 39 | HalconCpp::ReduceDomain(*m_hImage->hImage(), m_domain, &tmpImage); 40 | m_result->setHImage(tmpImage); 41 | } 42 | else 43 | { 44 | m_result->setHImage(*m_hImage->hImage()); 45 | } 46 | modelValidationState = NodeValidationState::Valid; 47 | modelValidationError = QString(); 48 | } 49 | catch (...) 50 | { 51 | modelValidationState = NodeValidationState::Warning; 52 | modelValidationError = QStringLiteral("缺失或运行失败!"); 53 | } 54 | 55 | Q_EMIT dataUpdated(outPortIndex); 56 | return true; 57 | } 58 | 59 | void HImageReduceDomainModel::OnNewRegionData(ShapeDataStruct _data) 60 | { 61 | *m_region_data = std::move(_data); 62 | m_domain = DrawShapeView::GetHRegionFromData(*m_region_data); 63 | 64 | RunTask(); 65 | } 66 | 67 | unsigned int HImageReduceDomainModel:: 68 | nPorts(PortType portType) const 69 | { 70 | unsigned int result = 1; 71 | 72 | switch (portType) 73 | { 74 | case PortType::In: 75 | result = 1; 76 | break; 77 | 78 | case PortType::Out: 79 | result = 1; 80 | 81 | default: 82 | break; 83 | } 84 | 85 | return result; 86 | } 87 | 88 | NodeValidationState HImageReduceDomainModel::validationState() const 89 | { 90 | return modelValidationState; 91 | } 92 | 93 | QString HImageReduceDomainModel::validationMessage() const 94 | { 95 | return modelValidationError; 96 | } 97 | 98 | QJsonObject HImageReduceDomainModel::save() const 99 | { 100 | QJsonObject result = NodeDataModel::save(); 101 | result.insert("m_region_data", QJsonConvert::convertToJson(*m_region_data)); 102 | return result; 103 | } 104 | 105 | void HImageReduceDomainModel::restore(QJsonObject const& _json) 106 | { 107 | QJsonConvert::convertFromJson(_json.value("m_region_data").toObject(), *m_region_data); 108 | m_domain = DrawShapeView::GetHRegionFromData(*m_region_data); 109 | } 110 | 111 | NodeDataType 112 | HImageReduceDomainModel::dataType(PortType, PortIndex) const 113 | { 114 | return HImageData().type(); 115 | } 116 | 117 | void HImageReduceDomainModel:: 118 | setInData(std::shared_ptr data, int portIndex) 119 | { 120 | auto hImageData = 121 | std::dynamic_pointer_cast(data); 122 | if (hImageData == nullptr) 123 | { 124 | return; 125 | } 126 | switch (portIndex) 127 | { 128 | case 0: 129 | m_hImage->setHImage(*hImageData->hImage()); 130 | break; 131 | default: 132 | break; 133 | } 134 | RunTask(); 135 | } 136 | 137 | std::shared_ptr 138 | HImageReduceDomainModel:: 139 | outData(PortIndex) 140 | { 141 | return std::dynamic_pointer_cast(m_result); 142 | } 143 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageReduceDomainModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "DataModelRegistry.hpp" 9 | #include "NodeDataModel.hpp" 10 | #include "halconcpp/HalconCpp.h" 11 | #include "HImageData.hpp" 12 | #include "HImageViewWidget.hpp" 13 | #include "DrawShapeView.hpp" 14 | 15 | using QtNodes::PortType; 16 | using QtNodes::PortIndex; 17 | using QtNodes::NodeData; 18 | using QtNodes::NodeDataType; 19 | using QtNodes::NodeDataModel; 20 | using QtNodes::NodeValidationState; 21 | using namespace HalconCpp; 22 | /** 23 | * \brief halcon 图像rgb2gray节点 24 | */ 25 | class HImageReduceDomainModel :public NodeDataModel 26 | { 27 | Q_OBJECT 28 | public: 29 | HImageReduceDomainModel(); 30 | virtual ~HImageReduceDomainModel() {} 31 | 32 | public: 33 | QString caption() const override 34 | { 35 | return QStringLiteral("选区掩膜"); 36 | } 37 | QString name() const override 38 | { 39 | return QStringLiteral("选区掩膜"); 40 | } 41 | virtual QString modelName() const 42 | { 43 | return QStringLiteral("选区掩膜"); 44 | } 45 | unsigned int 46 | nPorts(PortType portType) const override; 47 | 48 | NodeDataType 49 | dataType(PortType portType, PortIndex portIndex) const override; 50 | 51 | std::shared_ptr 52 | outData(PortIndex port) override; 53 | 54 | void 55 | setInData(std::shared_ptr, int) override; 56 | 57 | QWidget* 58 | embeddedWidget() override { return btn_drawReg; } 59 | 60 | bool 61 | resizable() const override { return false; } 62 | NodeValidationState 63 | validationState() const override; 64 | QString 65 | validationMessage() const override; 66 | QJsonObject save() const override; 67 | void restore(QJsonObject const&) override; 68 | protected: 69 | bool RunTask(); 70 | 71 | public slots: 72 | void OnNewRegionData(ShapeDataStruct _data); 73 | public: 74 | NodeValidationState modelValidationState = NodeValidationState::Warning; 75 | QString modelValidationError = QStringLiteral("图片输入未连接!"); 76 | private: 77 | //HWindow* h_window; 78 | QPushButton* btn_drawReg; 79 | HRegion m_domain; 80 | std::shared_ptr m_region_data; 81 | std::shared_ptr m_hImage; 82 | std::shared_ptr m_result; 83 | }; 84 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageShowModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HImageShowModel.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | HImageShowModel::HImageShowModel() 7 | { 8 | m_image_view = new HImageViewWidget(); 9 | m_image_view->installEventFilter(this); 10 | m_image_view->resize(200, 200); 11 | m_hImage = std::make_shared(); 12 | m_hRegion = std::make_shared(); 13 | #ifdef SHOWHALCON_OBJ 14 | h_window = new HWindow(0, 0, 512, 512, nullptr, "visible", ""); 15 | #endif 16 | 17 | } 18 | 19 | bool HImageShowModel::RunTask() 20 | { 21 | PortIndex const outPortIndex = 0; 22 | 23 | try 24 | { 25 | m_image_view->showImage(*m_hImage->hImage()); 26 | modelValidationState = NodeValidationState::Valid; 27 | modelValidationError = QString(); 28 | 29 | } 30 | catch (...) 31 | { 32 | modelValidationState = NodeValidationState::Warning; 33 | modelValidationError = QStringLiteral("缺失或运行失败!"); 34 | } 35 | 36 | Q_EMIT dataUpdated(outPortIndex); 37 | 38 | return true; 39 | } 40 | 41 | unsigned int HImageShowModel:: 42 | nPorts(PortType portType) const 43 | { 44 | unsigned int result = 1; 45 | 46 | switch (portType) 47 | { 48 | case PortType::In: 49 | result = 2; 50 | break; 51 | 52 | case PortType::Out: 53 | result = 2; 54 | 55 | default: 56 | break; 57 | } 58 | 59 | return result; 60 | } 61 | 62 | NodeValidationState HImageShowModel::validationState() const 63 | { 64 | return modelValidationState; 65 | } 66 | 67 | QString HImageShowModel::validationMessage() const 68 | { 69 | return modelValidationError; 70 | } 71 | 72 | bool HImageShowModel::eventFilter(QObject* object, QEvent* event) 73 | { 74 | 75 | return false; 76 | } 77 | 78 | NodeDataType 79 | HImageShowModel::dataType(PortType, PortIndex index) const 80 | { 81 | switch (index) 82 | { 83 | case 0: 84 | return HImageData().type(); 85 | break; 86 | case 1: 87 | return HRegionData().type(); 88 | break; 89 | } 90 | return HImageData().type(); 91 | } 92 | 93 | void HImageShowModel:: 94 | setInData(std::shared_ptr data, int portIndex) 95 | { 96 | if (data == nullptr) 97 | { 98 | return; 99 | } 100 | if (data->type() == m_hImage->type()) 101 | { 102 | auto dataPtr = std::dynamic_pointer_cast(data); 103 | if (!dataPtr->hImage()->IsInitialized()) 104 | { 105 | return; 106 | } 107 | m_hImage->setHImage(*dataPtr->hImage()); 108 | #ifdef SHOWHALCON_OBJ 109 | h_window->ClearWindow(); 110 | h_window->SetPart(HTuple(0), HTuple(0), m_hImage->hImage()->Height(), m_hImage->hImage()->Width()); 111 | HTuple chanels = m_hImage->hImage()->CountChannels(); 112 | if (chanels == 1) 113 | { 114 | h_window->DispImage(*m_hImage->hImage()); 115 | } 116 | else 117 | { 118 | h_window->DispColor(*m_hImage->hImage()); 119 | } 120 | #endif 121 | } 122 | else if (data->type() == m_hRegion->type()) 123 | { 124 | auto dataPtr = std::dynamic_pointer_cast(data); 125 | if (!dataPtr->hRegion()->IsInitialized()) 126 | { 127 | return; 128 | } 129 | m_hRegion->setHRegion(*dataPtr->hRegion()); 130 | m_hRegion->setSize(dataPtr->getSize()); 131 | 132 | HImage tmpImg = m_hRegion->hRegion()->RegionToBin(255, 0, 133 | m_hRegion->getSize().width(), m_hRegion->getSize().height()); 134 | m_hImage->setHImage(tmpImg); 135 | } 136 | RunTask(); 137 | } 138 | 139 | std::shared_ptr 140 | HImageShowModel:: 141 | outData(PortIndex index) 142 | { 143 | switch (index) 144 | { 145 | case 0: 146 | return std::dynamic_pointer_cast(m_hImage); 147 | break; 148 | case 1: 149 | return std::dynamic_pointer_cast(m_hRegion); 150 | break; 151 | } 152 | return std::dynamic_pointer_cast(m_hImage); 153 | } 154 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageShowModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "DataModelRegistry.hpp" 8 | #include "NodeDataModel.hpp" 9 | #include "halconcpp/HalconCpp.h" 10 | #include "HImageData.hpp" 11 | #include "HRegionData.hpp" 12 | #include "HImageViewWidget.hpp" 13 | 14 | using QtNodes::PortType; 15 | using QtNodes::PortIndex; 16 | using QtNodes::NodeData; 17 | using QtNodes::NodeDataType; 18 | using QtNodes::NodeDataModel; 19 | using QtNodes::NodeValidationState; 20 | using namespace HalconCpp; 21 | 22 | //#define SHOWHALCON_OBJ 23 | 24 | /** 25 | * \brief halcon 图像输入节点 26 | */ 27 | class HImageShowModel :public NodeDataModel 28 | { 29 | Q_OBJECT 30 | public: 31 | HImageShowModel(); 32 | virtual ~HImageShowModel() {} 33 | 34 | public: 35 | QString caption() const override 36 | { 37 | return QStringLiteral("图像显示"); 38 | } 39 | QString name() const override 40 | { 41 | return QStringLiteral("图像显示"); 42 | } 43 | virtual QString modelName() const 44 | { 45 | return QStringLiteral("图像显示"); 46 | } 47 | unsigned int 48 | nPorts(PortType portType) const override; 49 | 50 | NodeDataType 51 | dataType(PortType portType, PortIndex portIndex) const override; 52 | 53 | std::shared_ptr 54 | outData(PortIndex port) override; 55 | 56 | void 57 | setInData(std::shared_ptr, int) override; 58 | 59 | QWidget* 60 | embeddedWidget() override { return m_image_view; } 61 | 62 | bool 63 | resizable() const override { return true; } 64 | NodeValidationState 65 | validationState() const override; 66 | QString 67 | validationMessage() const override; 68 | protected: 69 | bool RunTask(); 70 | bool eventFilter(QObject* watched, QEvent* event) override; 71 | public: 72 | NodeValidationState modelValidationState = NodeValidationState::Warning; 73 | QString modelValidationError = QStringLiteral("图片输入未连接!"); 74 | private: 75 | #ifdef SHOWHALCON_OBJ 76 | HWindow* h_window; 77 | #endif 78 | 79 | std::shared_ptr m_hImage; 80 | std::shared_ptr m_hRegion; 81 | HImageViewWidget* m_image_view; 82 | }; 83 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageSplitChanelModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HImageSplitChanelModel.hpp" 2 | 3 | #include 4 | 5 | #include "halconcpp/HalconCpp.h" 6 | 7 | using namespace HalconCpp; 8 | 9 | HImageSplitChanelModel::HImageSplitChanelModel() 10 | { 11 | m_hImage = std::make_shared(); 12 | } 13 | 14 | bool HImageSplitChanelModel::RunTask() 15 | { 16 | 17 | auto img1 = m_hImage.lock(); 18 | try 19 | { 20 | if (img1) 21 | { 22 | HTuple imgChanels = img1->hImage()->CountChannels(); 23 | if (imgChanels == 3) 24 | { 25 | HImage chanR, chanG, chanB; 26 | Decompose3(*img1->hImage(), &chanR, &chanG, &chanB); 27 | if (m_resultR == nullptr) 28 | { 29 | m_resultR = std::make_shared(chanR); 30 | } 31 | if (m_resultG == nullptr) 32 | { 33 | m_resultG = std::make_shared(chanG); 34 | } 35 | if (m_resultB == nullptr) 36 | { 37 | m_resultB = std::make_shared(chanB); 38 | } 39 | m_resultR->setHImage(chanR); 40 | m_resultG->setHImage(chanG); 41 | m_resultB->setHImage(chanB); 42 | } 43 | else if (imgChanels == 1) 44 | { 45 | m_resultR = std::shared_ptr(m_hImage); 46 | m_resultG = std::shared_ptr(m_hImage); 47 | m_resultB = std::shared_ptr(m_hImage); 48 | } 49 | modelValidationState = NodeValidationState::Valid; 50 | modelValidationError = QString(); 51 | } 52 | } 53 | catch (...) 54 | { 55 | modelValidationState = NodeValidationState::Warning; 56 | modelValidationError = QStringLiteral("缺失或运行失败!"); 57 | m_resultR.reset(); 58 | m_resultG.reset(); 59 | m_resultB.reset(); 60 | } 61 | 62 | Q_EMIT dataUpdated((PortIndex)0); 63 | Q_EMIT dataUpdated((PortIndex)1); 64 | Q_EMIT dataUpdated((PortIndex)2); 65 | 66 | return true; 67 | } 68 | 69 | unsigned int HImageSplitChanelModel:: 70 | nPorts(PortType portType) const 71 | { 72 | unsigned int result = 1; 73 | 74 | switch (portType) 75 | { 76 | case PortType::In: 77 | result = 1; 78 | break; 79 | 80 | case PortType::Out: 81 | result = 3; 82 | 83 | default: 84 | break; 85 | } 86 | 87 | return result; 88 | } 89 | 90 | NodeValidationState HImageSplitChanelModel::validationState() const 91 | { 92 | return modelValidationState; 93 | } 94 | 95 | QString HImageSplitChanelModel::validationMessage() const 96 | { 97 | return modelValidationError; 98 | } 99 | 100 | NodeDataType 101 | HImageSplitChanelModel::dataType(PortType, PortIndex) const 102 | { 103 | return HImageData().type(); 104 | } 105 | 106 | void HImageSplitChanelModel:: 107 | setInData(std::shared_ptr data, int portIndex) 108 | { 109 | auto hImageData = 110 | std::dynamic_pointer_cast(data); 111 | 112 | switch (portIndex) 113 | { 114 | case 0: 115 | m_hImage = hImageData; 116 | break; 117 | default: 118 | break; 119 | } 120 | RunTask(); 121 | } 122 | 123 | std::shared_ptr 124 | HImageSplitChanelModel:: 125 | outData(PortIndex index) 126 | { 127 | 128 | if (index == 0) 129 | { 130 | return std::static_pointer_cast(m_resultR); 131 | } 132 | else if (index == 1) 133 | { 134 | return std::static_pointer_cast(m_resultG); 135 | } 136 | else 137 | { 138 | return std::static_pointer_cast(m_resultB); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageSplitChanelModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "DataModelRegistry.hpp" 8 | #include "NodeDataModel.hpp" 9 | #include "halconcpp/HalconCpp.h" 10 | #include "HImageData.hpp" 11 | #include "HImageViewWidget.hpp" 12 | 13 | using QtNodes::PortType; 14 | using QtNodes::PortIndex; 15 | using QtNodes::NodeData; 16 | using QtNodes::NodeDataType; 17 | using QtNodes::NodeDataModel; 18 | using QtNodes::NodeValidationState; 19 | using namespace HalconCpp; 20 | /** 21 | * \brief halcon 图像rgb2gray节点 22 | */ 23 | class HImageSplitChanelModel :public NodeDataModel 24 | { 25 | Q_OBJECT 26 | public: 27 | HImageSplitChanelModel(); 28 | virtual ~HImageSplitChanelModel() {} 29 | 30 | public: 31 | QString caption() const override 32 | { 33 | return QStringLiteral("SplitChanel"); 34 | } 35 | QString name() const override 36 | { 37 | return QStringLiteral("图像通道拆分"); 38 | } 39 | virtual QString modelName() const 40 | { 41 | return QStringLiteral("通道拆分"); 42 | } 43 | unsigned int 44 | nPorts(PortType portType) const override; 45 | 46 | NodeDataType 47 | dataType(PortType portType, PortIndex portIndex) const override; 48 | 49 | std::shared_ptr 50 | outData(PortIndex port) override; 51 | 52 | void 53 | setInData(std::shared_ptr, int) override; 54 | 55 | QWidget* 56 | embeddedWidget() override { return Q_NULLPTR; } 57 | 58 | bool 59 | resizable() const override { return true; } 60 | NodeValidationState 61 | validationState() const override; 62 | QString 63 | validationMessage() const override; 64 | protected: 65 | bool RunTask(); 66 | 67 | public: 68 | NodeValidationState modelValidationState = NodeValidationState::Warning; 69 | QString modelValidationError = QStringLiteral("图片输入未连接!"); 70 | private: 71 | std::weak_ptr m_hImage; 72 | std::shared_ptr m_resultR; 73 | std::shared_ptr m_resultG; 74 | std::shared_ptr m_resultB; 75 | }; 76 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageThresholdModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "DataModelRegistry.hpp" 8 | #include "NodeDataModel.hpp" 9 | #include "halconcpp/HalconCpp.h" 10 | #include "HImageData.hpp" 11 | #include "HRegionData.hpp" 12 | #include "HImageViewWidget.hpp" 13 | 14 | using QtNodes::PortType; 15 | using QtNodes::PortIndex; 16 | using QtNodes::NodeData; 17 | using QtNodes::NodeDataType; 18 | using QtNodes::NodeDataModel; 19 | using QtNodes::NodeValidationState; 20 | using namespace HalconCpp; 21 | /** 22 | * \brief halcon 图像rgb2gray节点 23 | */ 24 | class HImageThresholdModel :public NodeDataModel 25 | { 26 | Q_OBJECT 27 | public: 28 | HImageThresholdModel(); 29 | virtual ~HImageThresholdModel() = default; 30 | 31 | public: 32 | QString caption() const override 33 | { 34 | return QStringLiteral("二值化节点"); 35 | } 36 | QString name() const override 37 | { 38 | return QStringLiteral("二值化节点"); 39 | } 40 | virtual QString modelName() const 41 | { 42 | return QStringLiteral("二值化节点"); 43 | } 44 | unsigned int 45 | nPorts(PortType portType) const override; 46 | 47 | NodeDataType 48 | dataType(PortType portType, PortIndex portIndex) const override; 49 | 50 | std::shared_ptr 51 | outData(PortIndex port) override; 52 | 53 | void 54 | setInData(std::shared_ptr, int) override; 55 | 56 | QWidget* 57 | embeddedWidget() override { return m_widget; } 58 | 59 | bool 60 | resizable() const override { return true; } 61 | NodeValidationState 62 | validationState() const override; 63 | QString 64 | validationMessage() const override; 65 | 66 | QJsonObject save() const override; 67 | 68 | void restore(QJsonObject const&) override; 69 | 70 | protected: 71 | bool RunTask(); 72 | bool eventFilter(QObject* watched, QEvent* event) override; 73 | public: 74 | NodeValidationState modelValidationState = NodeValidationState::Warning; 75 | QString modelValidationError = QStringLiteral("图片输入未连接!"); 76 | private: 77 | std::shared_ptr m_hImage; 78 | std::shared_ptr m_domain; 79 | std::shared_ptr m_result; 80 | QSlider* m_minGraySlider; 81 | QSlider* m_maxGraySlider; 82 | QWidget* m_widget; 83 | }; 84 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HImageViewWidget.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "halconcpp/HalconCpp.h" 9 | using namespace HalconCpp; 10 | 11 | class HImageViewWidget 12 | :public QLabel 13 | { 14 | public: 15 | HImageViewWidget(QWidget* parent = Q_NULLPTR); 16 | virtual ~HImageViewWidget() {} 17 | void showImage(HImage const& _himg); 18 | public: 19 | static void HImageToQPixmap(HImage const& _img, QPixmap& tar_img); 20 | static bool QImage2HImage(QImage& from, HalconCpp::HImage& to); 21 | static void QPixmapToHRegion(QPixmap const& _pix, HRegion& tar_img); 22 | protected: 23 | void paintEvent(QPaintEvent* event) override; 24 | private: 25 | HImage cur_image; 26 | QPixmap* cur_pixmap; 27 | // 实例化画家对象,this指定的是绘图设备 28 | QPainter painter; 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HObjectData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "NodeDataModel.hpp" 6 | #include "halconcpp/HalconCpp.h" 7 | 8 | using QtNodes::NodeData; 9 | using QtNodes::NodeDataType; 10 | using namespace HalconCpp; 11 | 12 | class HObjecData :public NodeData 13 | { 14 | public: 15 | HObjecData() 16 | { 17 | m_hObject = HObject(); 18 | } 19 | HObjecData(HObject& _obj) 20 | { 21 | if (_obj.IsInitialized()) 22 | { 23 | m_hObject = _obj; 24 | } 25 | } 26 | virtual ~HObjecData() 27 | { 28 | 29 | } 30 | NodeDataType type() const override 31 | { 32 | return { "HObject","data" }; 33 | } 34 | 35 | HObject* hObject() { return &m_hObject; } 36 | 37 | void setObject(HObject const& _obj) 38 | { 39 | if (!_obj.IsInitialized()) 40 | { 41 | return; 42 | } 43 | m_hObject = _obj; 44 | } 45 | private: 46 | HObject m_hObject; 47 | }; 48 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionConnectModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HRegionConnectModel.hpp" 2 | #include 3 | 4 | #include "halconcpp/HalconCpp.h" 5 | 6 | using namespace HalconCpp; 7 | 8 | HRegionConnectModel::HRegionConnectModel() 9 | { 10 | m_InRegion = std::make_shared(); 11 | m_result = std::make_shared(); 12 | 13 | } 14 | 15 | bool HRegionConnectModel::RunTask() 16 | { 17 | PortIndex const outPortIndex = 0; 18 | if (m_InRegion->hRegion() == nullptr) 19 | { 20 | return false; 21 | } 22 | try 23 | { 24 | m_result->setHRegion(m_InRegion->hRegion()->Connection()); 25 | 26 | m_result->setSize(m_InRegion->getSize()); 27 | 28 | modelValidationState = NodeValidationState::Valid; 29 | modelValidationError = QString(); 30 | } 31 | catch (...) 32 | { 33 | modelValidationState = NodeValidationState::Warning; 34 | modelValidationError = QStringLiteral("缺失或运行失败!"); 35 | } 36 | 37 | Q_EMIT dataUpdated(outPortIndex); 38 | 39 | return true; 40 | } 41 | 42 | bool HRegionConnectModel::eventFilter(QObject* watched, QEvent* event) 43 | { 44 | 45 | return false; 46 | } 47 | 48 | unsigned int HRegionConnectModel:: 49 | nPorts(PortType portType) const 50 | { 51 | unsigned int result = 1; 52 | 53 | switch (portType) 54 | { 55 | case PortType::In: 56 | result = 1; 57 | break; 58 | 59 | case PortType::Out: 60 | result = 1; 61 | 62 | default: 63 | break; 64 | } 65 | 66 | return result; 67 | } 68 | 69 | NodeValidationState HRegionConnectModel::validationState() const 70 | { 71 | return modelValidationState; 72 | } 73 | 74 | QString HRegionConnectModel::validationMessage() const 75 | { 76 | return modelValidationError; 77 | } 78 | 79 | NodeDataType 80 | HRegionConnectModel::dataType(PortType, PortIndex) const 81 | { 82 | return HRegionData().type(); 83 | } 84 | 85 | void HRegionConnectModel:: 86 | setInData(std::shared_ptr data, int portIndex) 87 | { 88 | auto hRegionData = 89 | std::dynamic_pointer_cast(data); 90 | if (hRegionData == nullptr) 91 | { 92 | return; 93 | } 94 | switch (portIndex) 95 | { 96 | case 0: 97 | m_InRegion->setHRegion(*hRegionData->hRegion()); 98 | m_InRegion->setSize(hRegionData->getSize()); 99 | break; 100 | default: 101 | break; 102 | } 103 | RunTask(); 104 | } 105 | 106 | std::shared_ptr 107 | HRegionConnectModel:: 108 | outData(PortIndex index) 109 | { 110 | switch (index) 111 | { 112 | case 0: 113 | return std::dynamic_pointer_cast(m_result); 114 | break; 115 | case 1: 116 | break; 117 | default: 118 | break; 119 | } 120 | return std::dynamic_pointer_cast(m_result); 121 | } 122 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionConnectModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "DataModelRegistry.hpp" 9 | #include "NodeDataModel.hpp" 10 | #include "halconcpp/HalconCpp.h" 11 | #include "HImageData.hpp" 12 | #include "HRegionData.hpp" 13 | #include "HImageViewWidget.hpp" 14 | 15 | using QtNodes::PortType; 16 | using QtNodes::PortIndex; 17 | using QtNodes::NodeData; 18 | using QtNodes::NodeDataType; 19 | using QtNodes::NodeDataModel; 20 | using QtNodes::NodeValidationState; 21 | using namespace HalconCpp; 22 | /** 23 | * \brief halcon 图像rgb2gray节点 24 | */ 25 | class HRegionConnectModel :public NodeDataModel 26 | { 27 | Q_OBJECT 28 | public: 29 | HRegionConnectModel(); 30 | virtual ~HRegionConnectModel() {} 31 | 32 | public: 33 | QString caption() const override 34 | { 35 | return QStringLiteral("非联通区域"); 36 | } 37 | QString name() const override 38 | { 39 | return QStringLiteral("非联通区域"); 40 | } 41 | virtual QString modelName() const 42 | { 43 | return QStringLiteral("非联通区域"); 44 | } 45 | unsigned int 46 | nPorts(PortType portType) const override; 47 | 48 | NodeDataType 49 | dataType(PortType portType, PortIndex portIndex) const override; 50 | 51 | std::shared_ptr 52 | outData(PortIndex port) override; 53 | 54 | void 55 | setInData(std::shared_ptr, int) override; 56 | 57 | QWidget* 58 | embeddedWidget() override { return nullptr; } 59 | 60 | bool 61 | resizable() const override { return false; } 62 | NodeValidationState 63 | validationState() const override; 64 | QString 65 | validationMessage() const override; 66 | 67 | protected: 68 | bool RunTask(); 69 | bool eventFilter(QObject* watched, QEvent* event) override; 70 | public: 71 | NodeValidationState modelValidationState = NodeValidationState::Warning; 72 | QString modelValidationError = QStringLiteral("区域输入未连接!"); 73 | private: 74 | std::shared_ptr m_InRegion; 75 | std::shared_ptr m_result; 76 | }; 77 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "NodeDataModel.hpp" 6 | #include "halconcpp/HalconCpp.h" 7 | 8 | using QtNodes::NodeData; 9 | using QtNodes::NodeDataType; 10 | using namespace HalconCpp; 11 | 12 | class HRegionData :public NodeData 13 | { 14 | public: 15 | HRegionData() 16 | { 17 | m_hRegion = HRegion(); 18 | } 19 | HRegionData(HRegion& _hregion) 20 | { 21 | if (_hregion.IsInitialized()) 22 | { 23 | m_hRegion = _hregion; 24 | } 25 | } 26 | virtual ~HRegionData() 27 | { 28 | 29 | } 30 | NodeDataType type() const override 31 | { 32 | return { "HRegion","Region" }; 33 | } 34 | HRegion* hRegion() { return &m_hRegion; } 35 | void setHRegion(HRegion const& _hregion) 36 | { 37 | if (!_hregion.IsInitialized()) 38 | { 39 | return; 40 | } 41 | m_hRegion = _hregion; 42 | } 43 | QSize getSize() 44 | { 45 | return m_size; 46 | } 47 | void setSize(QSize const& _size) 48 | { 49 | m_size = _size; 50 | } 51 | private: 52 | HRegion m_hRegion; 53 | QSize m_size; 54 | }; 55 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionDifferenceModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HRegionDifferenceModel.hpp" 2 | #include 3 | 4 | #include "halconcpp/HalconCpp.h" 5 | 6 | using namespace HalconCpp; 7 | 8 | HRegionDifferenceModel::HRegionDifferenceModel() 9 | { 10 | m_InRegion = std::make_shared(); 11 | m_result = std::make_shared(); 12 | m_InRegionDiv = std::make_shared(); 13 | 14 | } 15 | 16 | QString HRegionDifferenceModel::portCaption(PortType port, PortIndex port_index) const 17 | { 18 | if (port == PortType::In) 19 | { 20 | switch (port_index) 21 | { 22 | case 0: 23 | return "Ori"; 24 | break; 25 | case 1: 26 | return "Div"; 27 | break; 28 | } 29 | } 30 | else if (port == PortType::Out) 31 | { 32 | switch (port_index) 33 | { 34 | case 0: 35 | return "Res"; 36 | break; 37 | } 38 | } 39 | 40 | return HRegionDifferenceModel::portCaption(port, port_index); 41 | } 42 | 43 | bool HRegionDifferenceModel::RunTask() 44 | { 45 | PortIndex const outPortIndex = 0; 46 | if (m_InRegion->hRegion() == nullptr) 47 | { 48 | return false; 49 | } 50 | try 51 | { 52 | HalconCpp::Difference(*m_InRegion->hRegion(), *m_InRegionDiv->hRegion(), m_result->hRegion()); 53 | 54 | m_result->setSize(m_InRegion->getSize()); 55 | 56 | modelValidationState = NodeValidationState::Valid; 57 | modelValidationError = QString(); 58 | } 59 | catch (...) 60 | { 61 | modelValidationState = NodeValidationState::Warning; 62 | modelValidationError = QStringLiteral("缺失或运行失败!"); 63 | } 64 | 65 | Q_EMIT dataUpdated(outPortIndex); 66 | 67 | return true; 68 | } 69 | 70 | bool HRegionDifferenceModel::eventFilter(QObject* watched, QEvent* event) 71 | { 72 | 73 | return false; 74 | } 75 | 76 | unsigned int HRegionDifferenceModel:: 77 | nPorts(PortType portType) const 78 | { 79 | unsigned int result = 1; 80 | 81 | switch (portType) 82 | { 83 | case PortType::In: 84 | result = 2; 85 | break; 86 | 87 | case PortType::Out: 88 | result = 1; 89 | 90 | default: 91 | break; 92 | } 93 | 94 | return result; 95 | } 96 | 97 | NodeValidationState HRegionDifferenceModel::validationState() const 98 | { 99 | return modelValidationState; 100 | } 101 | 102 | QString HRegionDifferenceModel::validationMessage() const 103 | { 104 | return modelValidationError; 105 | } 106 | 107 | NodeDataType 108 | HRegionDifferenceModel::dataType(PortType, PortIndex) const 109 | { 110 | return HRegionData().type(); 111 | } 112 | 113 | void HRegionDifferenceModel:: 114 | setInData(std::shared_ptr data, int portIndex) 115 | { 116 | auto hRegionData = 117 | std::dynamic_pointer_cast(data); 118 | if (hRegionData == nullptr) 119 | { 120 | return; 121 | } 122 | switch (portIndex) 123 | { 124 | case 0: 125 | m_InRegion->setHRegion(*hRegionData->hRegion()); 126 | m_InRegion->setSize(hRegionData->getSize()); 127 | break; 128 | case 1: 129 | m_InRegionDiv->setHRegion(*hRegionData->hRegion()); 130 | m_InRegionDiv->setSize(hRegionData->getSize()); 131 | break; 132 | default: 133 | break; 134 | } 135 | RunTask(); 136 | } 137 | 138 | std::shared_ptr 139 | HRegionDifferenceModel:: 140 | outData(PortIndex index) 141 | { 142 | switch (index) 143 | { 144 | case 0: 145 | return std::dynamic_pointer_cast(m_result); 146 | break; 147 | case 1: 148 | break; 149 | default: 150 | break; 151 | } 152 | return std::dynamic_pointer_cast(m_result); 153 | } 154 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionDifferenceModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "DataModelRegistry.hpp" 9 | #include "NodeDataModel.hpp" 10 | #include "halconcpp/HalconCpp.h" 11 | #include "HImageData.hpp" 12 | #include "HRegionData.hpp" 13 | #include "HImageViewWidget.hpp" 14 | 15 | using QtNodes::PortType; 16 | using QtNodes::PortIndex; 17 | using QtNodes::NodeData; 18 | using QtNodes::NodeDataType; 19 | using QtNodes::NodeDataModel; 20 | using QtNodes::NodeValidationState; 21 | using namespace HalconCpp; 22 | /** 23 | * \brief halcon 图像rgb2gray节点 24 | */ 25 | class HRegionDifferenceModel :public NodeDataModel 26 | { 27 | Q_OBJECT 28 | public: 29 | HRegionDifferenceModel(); 30 | virtual ~HRegionDifferenceModel() {} 31 | 32 | public: 33 | QString caption() const override 34 | { 35 | return QStringLiteral("相减区域"); 36 | } 37 | QString name() const override 38 | { 39 | return QStringLiteral("相减区域"); 40 | } 41 | virtual QString modelName() const 42 | { 43 | return QStringLiteral("相减区域"); 44 | } 45 | unsigned int 46 | nPorts(PortType portType) const override; 47 | 48 | NodeDataType 49 | dataType(PortType portType, PortIndex portIndex) const override; 50 | 51 | std::shared_ptr 52 | outData(PortIndex port) override; 53 | 54 | void 55 | setInData(std::shared_ptr, int) override; 56 | 57 | QWidget* 58 | embeddedWidget() override { return nullptr; } 59 | 60 | bool 61 | resizable() const override { return false; } 62 | NodeValidationState 63 | validationState() const override; 64 | QString 65 | validationMessage() const override; 66 | bool portCaptionVisible(PortType, PortIndex) const override { return true; } 67 | QString portCaption(PortType, PortIndex) const override; 68 | protected: 69 | bool RunTask(); 70 | bool eventFilter(QObject* watched, QEvent* event) override; 71 | public: 72 | NodeValidationState modelValidationState = NodeValidationState::Warning; 73 | QString modelValidationError = QStringLiteral("区域输入未连接!"); 74 | private: 75 | std::shared_ptr m_InRegion; 76 | std::shared_ptr m_InRegionDiv; 77 | std::shared_ptr m_result; 78 | }; 79 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionFillUpShapeModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "DataModelRegistry.hpp" 12 | #include "NodeDataModel.hpp" 13 | #include "halconcpp/HalconCpp.h" 14 | #include "HRegionData.hpp" 15 | #include "HImageViewWidget.hpp" 16 | 17 | using QtNodes::PortType; 18 | using QtNodes::PortIndex; 19 | using QtNodes::NodeData; 20 | using QtNodes::NodeDataType; 21 | using QtNodes::NodeDataModel; 22 | using QtNodes::NodeValidationState; 23 | using namespace HalconCpp; 24 | /** 25 | * \brief halcon 图像rgb2gray节点 26 | */ 27 | class HRegionFillUpShapeModel :public NodeDataModel 28 | { 29 | Q_OBJECT 30 | public: 31 | HRegionFillUpShapeModel(); 32 | virtual ~HRegionFillUpShapeModel() {} 33 | 34 | public: 35 | QString caption() const override 36 | { 37 | return QStringLiteral("填充区域"); 38 | } 39 | QString name() const override 40 | { 41 | return QStringLiteral("填充区域"); 42 | } 43 | virtual QString modelName() const 44 | { 45 | return QStringLiteral("填充区域"); 46 | } 47 | unsigned int 48 | nPorts(PortType portType) const override; 49 | 50 | NodeDataType 51 | dataType(PortType portType, PortIndex portIndex) const override; 52 | 53 | std::shared_ptr 54 | outData(PortIndex port) override; 55 | 56 | void 57 | setInData(std::shared_ptr, int) override; 58 | 59 | QWidget* 60 | embeddedWidget() override { return m_widget; } 61 | 62 | bool 63 | resizable() const override { return false; } 64 | NodeValidationState 65 | validationState() const override; 66 | QString 67 | validationMessage() const override; 68 | QJsonObject save() const override; 69 | 70 | void restore(QJsonObject const&) override; 71 | protected: 72 | bool RunTask(); 73 | 74 | public: 75 | NodeValidationState modelValidationState = NodeValidationState::Warning; 76 | QString modelValidationError = QStringLiteral("图片输入未连接!"); 77 | private: 78 | QString m_feature; 79 | double m_minval = 0.0; 80 | double m_maxval = 100.0; 81 | std::shared_ptr m_hRegion; 82 | std::shared_ptr m_result; 83 | QWidget* m_widget; 84 | QVBoxLayout* m_host; 85 | QComboBox* m_combo_feature; 86 | QLineEdit* m_minvalEdit; 87 | QLineEdit* m_maxvalEdit; 88 | }; 89 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionOpenCircleModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HRegionOpenCircleModel.hpp" 2 | #include 3 | 4 | #include "halconcpp/HalconCpp.h" 5 | 6 | using namespace HalconCpp; 7 | 8 | HRegionOpenCircleModel::HRegionOpenCircleModel() 9 | { 10 | m_hRegion = std::make_shared(); 11 | m_result = std::make_shared(); 12 | 13 | m_maxvalEdit = new QLineEdit(); 14 | m_maxvalEdit->setFixedWidth(80); 15 | m_maxvalEdit->setText("9.0"); 16 | 17 | connect(m_maxvalEdit, &QLineEdit::textChanged, [=]() 18 | { 19 | m_maxval = m_maxvalEdit->text().toDouble(); 20 | RunTask(); 21 | }); 22 | } 23 | 24 | bool HRegionOpenCircleModel::RunTask() 25 | { 26 | Q_EMIT computingStarted(); 27 | PortIndex const outPortIndex = 0; 28 | try 29 | { 30 | HalconCpp::OpeningCircle( 31 | *m_hRegion->hRegion(), 32 | m_result->hRegion(), 33 | m_maxval); 34 | modelValidationState = NodeValidationState::Valid; 35 | modelValidationError = QString(); 36 | } 37 | catch (...) 38 | { 39 | modelValidationState = NodeValidationState::Warning; 40 | modelValidationError = QStringLiteral("缺失或运行失败!"); 41 | } 42 | 43 | Q_EMIT dataUpdated(outPortIndex); 44 | Q_EMIT computingFinished(); 45 | return true; 46 | } 47 | 48 | unsigned int HRegionOpenCircleModel:: 49 | nPorts(PortType portType) const 50 | { 51 | unsigned int result = 1; 52 | 53 | switch (portType) 54 | { 55 | case PortType::In: 56 | result = 1; 57 | break; 58 | 59 | case PortType::Out: 60 | result = 1; 61 | 62 | default: 63 | break; 64 | } 65 | 66 | return result; 67 | } 68 | 69 | NodeValidationState HRegionOpenCircleModel::validationState() const 70 | { 71 | return modelValidationState; 72 | } 73 | 74 | QString HRegionOpenCircleModel::validationMessage() const 75 | { 76 | return modelValidationError; 77 | } 78 | 79 | QJsonObject HRegionOpenCircleModel::save() const 80 | { 81 | QJsonObject result = NodeDataModel::save(); 82 | 83 | result.insert("m_maxval", m_maxval); 84 | return result; 85 | } 86 | 87 | void HRegionOpenCircleModel::restore(QJsonObject const& json_values) 88 | { 89 | NodeDataModel::restore(json_values); 90 | m_maxval = json_values.value("m_maxval").toDouble(); 91 | m_maxvalEdit->setText(QString::number(m_maxval)); 92 | } 93 | 94 | NodeDataType 95 | HRegionOpenCircleModel::dataType(PortType, PortIndex) const 96 | { 97 | return HRegionData().type(); 98 | } 99 | 100 | void HRegionOpenCircleModel:: 101 | setInData(std::shared_ptr data, int portIndex) 102 | { 103 | auto hImageData = 104 | std::dynamic_pointer_cast(data); 105 | if (hImageData == nullptr) 106 | { 107 | return; 108 | } 109 | switch (portIndex) 110 | { 111 | case 0: 112 | m_hRegion->setHRegion(*hImageData->hRegion()); 113 | m_result->setSize(hImageData->getSize()); 114 | break; 115 | default: 116 | break; 117 | } 118 | RunTask(); 119 | } 120 | 121 | std::shared_ptr 122 | HRegionOpenCircleModel:: 123 | outData(PortIndex) 124 | { 125 | return std::static_pointer_cast(m_result); 126 | } 127 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionOpenCircleModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "DataModelRegistry.hpp" 12 | #include "NodeDataModel.hpp" 13 | #include "halconcpp/HalconCpp.h" 14 | #include "HRegionData.hpp" 15 | #include "HImageViewWidget.hpp" 16 | 17 | using QtNodes::PortType; 18 | using QtNodes::PortIndex; 19 | using QtNodes::NodeData; 20 | using QtNodes::NodeDataType; 21 | using QtNodes::NodeDataModel; 22 | using QtNodes::NodeValidationState; 23 | using namespace HalconCpp; 24 | /** 25 | * \brief halcon 图像rgb2gray节点 26 | */ 27 | class HRegionOpenCircleModel :public NodeDataModel 28 | { 29 | Q_OBJECT 30 | public: 31 | HRegionOpenCircleModel(); 32 | virtual ~HRegionOpenCircleModel() {} 33 | 34 | public: 35 | QString caption() const override 36 | { 37 | return QStringLiteral("开放圆"); 38 | } 39 | QString name() const override 40 | { 41 | return QStringLiteral("开放圆"); 42 | } 43 | virtual QString modelName() const 44 | { 45 | return QStringLiteral("开放圆"); 46 | } 47 | unsigned int 48 | nPorts(PortType portType) const override; 49 | 50 | NodeDataType 51 | dataType(PortType portType, PortIndex portIndex) const override; 52 | 53 | std::shared_ptr 54 | outData(PortIndex port) override; 55 | 56 | void 57 | setInData(std::shared_ptr, int) override; 58 | 59 | QWidget* 60 | embeddedWidget() override { return m_maxvalEdit; } 61 | 62 | bool 63 | resizable() const override { return false; } 64 | NodeValidationState 65 | validationState() const override; 66 | QString 67 | validationMessage() const override; 68 | QJsonObject save() const override; 69 | 70 | void restore(QJsonObject const&) override; 71 | protected: 72 | bool RunTask(); 73 | 74 | public: 75 | NodeValidationState modelValidationState = NodeValidationState::Warning; 76 | QString modelValidationError = QStringLiteral("图片输入未连接!"); 77 | private: 78 | double m_maxval = 100.0; 79 | std::shared_ptr m_hRegion; 80 | std::shared_ptr m_result; 81 | QLineEdit* m_maxvalEdit; 82 | }; 83 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionSelectModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "DataModelRegistry.hpp" 10 | #include "NodeDataModel.hpp" 11 | #include "halconcpp/HalconCpp.h" 12 | #include "HImageData.hpp" 13 | #include "HRegionData.hpp" 14 | #include "HImageViewWidget.hpp" 15 | 16 | using QtNodes::PortType; 17 | using QtNodes::PortIndex; 18 | using QtNodes::NodeData; 19 | using QtNodes::NodeDataType; 20 | using QtNodes::NodeDataModel; 21 | using QtNodes::NodeValidationState; 22 | using namespace HalconCpp; 23 | /** 24 | * \brief halcon 图像rgb2gray节点 25 | */ 26 | class HRegionSelectModel :public NodeDataModel 27 | { 28 | Q_OBJECT 29 | public: 30 | HRegionSelectModel(); 31 | virtual ~HRegionSelectModel() {} 32 | 33 | public: 34 | QString caption() const override 35 | { 36 | return QStringLiteral("选择区域"); 37 | } 38 | QString name() const override 39 | { 40 | return QStringLiteral("选择区域"); 41 | } 42 | virtual QString modelName() const 43 | { 44 | return QStringLiteral("选择区域"); 45 | } 46 | unsigned int 47 | nPorts(PortType portType) const override; 48 | 49 | NodeDataType 50 | dataType(PortType portType, PortIndex portIndex) const override; 51 | 52 | std::shared_ptr 53 | outData(PortIndex port) override; 54 | 55 | void 56 | setInData(std::shared_ptr, int) override; 57 | 58 | QWidget* 59 | embeddedWidget() override { return m_widget; } 60 | 61 | bool 62 | resizable() const override { return true; } 63 | NodeValidationState 64 | validationState() const override; 65 | QString 66 | validationMessage() const override; 67 | 68 | QJsonObject save() const override; 69 | 70 | void restore(QJsonObject const&) override; 71 | 72 | protected: 73 | bool RunTask(); 74 | bool eventFilter(QObject* watched, QEvent* event) override; 75 | public: 76 | NodeValidationState modelValidationState = NodeValidationState::Warning; 77 | QString modelValidationError = QStringLiteral("区域输入未连接!"); 78 | private: 79 | std::shared_ptr m_InRegion; 80 | std::shared_ptr m_result; 81 | QComboBox* combo_feature; 82 | QComboBox* combo_operation; 83 | QLineEdit* m_minValue; 84 | QLineEdit* m_maxValue; 85 | QWidget* m_widget; 86 | QString m_cur_feature; 87 | QString m_cur_operation; 88 | int minVal; 89 | int maxVal; 90 | }; 91 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionSelectShapeStdModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "DataModelRegistry.hpp" 10 | #include "NodeDataModel.hpp" 11 | #include "halconcpp/HalconCpp.h" 12 | #include "HImageData.hpp" 13 | #include "HRegionData.hpp" 14 | #include "HImageViewWidget.hpp" 15 | 16 | using QtNodes::PortType; 17 | using QtNodes::PortIndex; 18 | using QtNodes::NodeData; 19 | using QtNodes::NodeDataType; 20 | using QtNodes::NodeDataModel; 21 | using QtNodes::NodeValidationState; 22 | using namespace HalconCpp; 23 | /** 24 | * \brief halcon shapeTrans节点 25 | */ 26 | class HRegionSelectShapeStdModel :public NodeDataModel 27 | { 28 | Q_OBJECT 29 | public: 30 | HRegionSelectShapeStdModel(); 31 | virtual ~HRegionSelectShapeStdModel() {} 32 | 33 | public: 34 | QString caption() const override 35 | { 36 | return QStringLiteral("选择形状"); 37 | } 38 | QString name() const override 39 | { 40 | return QStringLiteral("选择形状"); 41 | } 42 | virtual QString modelName() const 43 | { 44 | return QStringLiteral("选择形状"); 45 | } 46 | unsigned int 47 | nPorts(PortType portType) const override; 48 | 49 | NodeDataType 50 | dataType(PortType portType, PortIndex portIndex) const override; 51 | 52 | std::shared_ptr 53 | outData(PortIndex port) override; 54 | 55 | void 56 | setInData(std::shared_ptr, int) override; 57 | 58 | QWidget* 59 | embeddedWidget() override { return m_widget; } 60 | 61 | bool 62 | resizable() const override { return false; } 63 | NodeValidationState 64 | validationState() const override; 65 | QString 66 | validationMessage() const override; 67 | 68 | QJsonObject save() const override; 69 | 70 | void restore(QJsonObject const&) override; 71 | 72 | protected: 73 | bool RunTask(); 74 | bool eventFilter(QObject* watched, QEvent* event) override; 75 | public: 76 | NodeValidationState modelValidationState = NodeValidationState::Warning; 77 | QString modelValidationError = QStringLiteral("区域输入未连接!"); 78 | private: 79 | std::shared_ptr m_InRegion; 80 | std::shared_ptr m_result; 81 | QLineEdit* m_percentEdit; 82 | QComboBox* combo_feature; 83 | QWidget* m_widget; 84 | QString m_cur_feature; 85 | double m_percent; 86 | }; 87 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionShapeTransModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HRegionShapeTransModel.hpp" 2 | #include 3 | #include "halconcpp/HalconCpp.h" 4 | 5 | using namespace HalconCpp; 6 | 7 | HRegionShapeTransModel::HRegionShapeTransModel() 8 | { 9 | m_widget = new QWidget(); 10 | m_widget->setAttribute(Qt::WA_NoSystemBackground); 11 | m_widget->setFixedSize(150, 50); 12 | combo_feature = new QComboBox(m_widget); 13 | 14 | combo_feature->move(0, 10); 15 | 16 | combo_feature->addItem("convex"); 17 | combo_feature->addItem("ellipse"); 18 | combo_feature->addItem("outer_circle"); 19 | combo_feature->addItem("inner_circle"); 20 | combo_feature->addItem("rectangle1"); 21 | combo_feature->addItem("rectangle2"); 22 | combo_feature->addItem("inner_rectangle1"); 23 | combo_feature->addItem("inner_rectangle2"); 24 | 25 | m_InRegion = std::make_shared(); 26 | m_result = std::make_shared(); 27 | 28 | connect(combo_feature, &QComboBox::currentTextChanged, [=]() 29 | { 30 | RunTask(); 31 | }); 32 | } 33 | 34 | bool HRegionShapeTransModel::RunTask() 35 | { 36 | PortIndex const outPortIndex = 0; 37 | if (m_InRegion->hRegion() == nullptr) 38 | { 39 | return false; 40 | } 41 | try 42 | { 43 | m_cur_feature = combo_feature->currentText(); 44 | m_result->setHRegion(m_InRegion->hRegion()->ShapeTrans( 45 | combo_feature->currentText().toStdString().c_str() 46 | )); 47 | m_result->setSize(m_InRegion->getSize()); 48 | 49 | modelValidationState = NodeValidationState::Valid; 50 | modelValidationError = QString(); 51 | } 52 | catch (...) 53 | { 54 | modelValidationState = NodeValidationState::Warning; 55 | modelValidationError = QStringLiteral("缺失或运行失败!"); 56 | } 57 | 58 | Q_EMIT dataUpdated(outPortIndex); 59 | 60 | return true; 61 | } 62 | 63 | bool HRegionShapeTransModel::eventFilter(QObject* watched, QEvent* event) 64 | { 65 | 66 | return false; 67 | } 68 | 69 | unsigned int HRegionShapeTransModel:: 70 | nPorts(PortType portType) const 71 | { 72 | unsigned int result = 1; 73 | 74 | switch (portType) 75 | { 76 | case PortType::In: 77 | result = 1; 78 | break; 79 | 80 | case PortType::Out: 81 | result = 1; 82 | 83 | default: 84 | break; 85 | } 86 | 87 | return result; 88 | } 89 | 90 | NodeValidationState HRegionShapeTransModel::validationState() const 91 | { 92 | return modelValidationState; 93 | } 94 | 95 | QString HRegionShapeTransModel::validationMessage() const 96 | { 97 | return modelValidationError; 98 | } 99 | 100 | QJsonObject HRegionShapeTransModel::save() const 101 | { 102 | QJsonObject result = NodeDataModel::save(); 103 | result.insert("m_cur_feature", combo_feature->currentText()); 104 | return result; 105 | } 106 | 107 | void HRegionShapeTransModel::restore(QJsonObject const& p) 108 | { 109 | combo_feature->setCurrentText(p["m_cur_feature"].toString("rectangle1")); 110 | } 111 | 112 | NodeDataType 113 | HRegionShapeTransModel::dataType(PortType, PortIndex) const 114 | { 115 | return HRegionData().type(); 116 | } 117 | 118 | void HRegionShapeTransModel:: 119 | setInData(std::shared_ptr data, int portIndex) 120 | { 121 | auto hRegionData = 122 | std::dynamic_pointer_cast(data); 123 | if (hRegionData == nullptr) 124 | { 125 | return; 126 | } 127 | switch (portIndex) 128 | { 129 | case 0: 130 | m_InRegion->setHRegion(*hRegionData->hRegion()); 131 | m_InRegion->setSize(hRegionData->getSize()); 132 | break; 133 | default: 134 | break; 135 | } 136 | RunTask(); 137 | } 138 | 139 | std::shared_ptr 140 | HRegionShapeTransModel:: 141 | outData(PortIndex index) 142 | { 143 | switch (index) 144 | { 145 | case 0: 146 | return std::dynamic_pointer_cast(m_result); 147 | break; 148 | case 1: 149 | break; 150 | default: 151 | break; 152 | } 153 | return std::dynamic_pointer_cast(m_result); 154 | } 155 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionShapeTransModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "DataModelRegistry.hpp" 10 | #include "NodeDataModel.hpp" 11 | #include "halconcpp/HalconCpp.h" 12 | #include "HImageData.hpp" 13 | #include "HRegionData.hpp" 14 | #include "HImageViewWidget.hpp" 15 | 16 | using QtNodes::PortType; 17 | using QtNodes::PortIndex; 18 | using QtNodes::NodeData; 19 | using QtNodes::NodeDataType; 20 | using QtNodes::NodeDataModel; 21 | using QtNodes::NodeValidationState; 22 | using namespace HalconCpp; 23 | /** 24 | * \brief halcon shapeTrans节点 25 | */ 26 | class HRegionShapeTransModel :public NodeDataModel 27 | { 28 | Q_OBJECT 29 | public: 30 | HRegionShapeTransModel(); 31 | virtual ~HRegionShapeTransModel() {} 32 | 33 | public: 34 | QString caption() const override 35 | { 36 | return QStringLiteral("仿形变换"); 37 | } 38 | QString name() const override 39 | { 40 | return QStringLiteral("仿形变换"); 41 | } 42 | virtual QString modelName() const 43 | { 44 | return QStringLiteral("仿形变换"); 45 | } 46 | unsigned int 47 | nPorts(PortType portType) const override; 48 | 49 | NodeDataType 50 | dataType(PortType portType, PortIndex portIndex) const override; 51 | 52 | std::shared_ptr 53 | outData(PortIndex port) override; 54 | 55 | void 56 | setInData(std::shared_ptr, int) override; 57 | 58 | QWidget* 59 | embeddedWidget() override { return m_widget; } 60 | 61 | bool 62 | resizable() const override { return true; } 63 | NodeValidationState 64 | validationState() const override; 65 | QString 66 | validationMessage() const override; 67 | 68 | QJsonObject save() const override; 69 | 70 | void restore(QJsonObject const&) override; 71 | 72 | protected: 73 | bool RunTask(); 74 | bool eventFilter(QObject* watched, QEvent* event) override; 75 | public: 76 | NodeValidationState modelValidationState = NodeValidationState::Warning; 77 | QString modelValidationError = QStringLiteral("区域输入未连接!"); 78 | private: 79 | std::shared_ptr m_InRegion; 80 | std::shared_ptr m_result; 81 | QComboBox* combo_feature; 82 | QWidget* m_widget; 83 | QString m_cur_feature; 84 | 85 | }; 86 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionUnionModel.cpp: -------------------------------------------------------------------------------- 1 | #include "HRegionUnionModel.hpp" 2 | #include 3 | 4 | #include "halconcpp/HalconCpp.h" 5 | 6 | using namespace HalconCpp; 7 | 8 | HRegionUnionModel::HRegionUnionModel() 9 | { 10 | m_InRegion = std::make_shared(); 11 | m_result = std::make_shared(); 12 | 13 | } 14 | 15 | QString HRegionUnionModel::portCaption(PortType port, PortIndex port_index) const 16 | { 17 | if (port == PortType::In) 18 | { 19 | switch (port_index) 20 | { 21 | case 0: 22 | return "Ori"; 23 | break; 24 | case 1: 25 | return "Add"; 26 | break; 27 | } 28 | } 29 | else if (port == PortType::Out) 30 | { 31 | switch (port_index) 32 | { 33 | case 0: 34 | return "Res"; 35 | break; 36 | } 37 | } 38 | 39 | return NodeDataModel::portCaption(port, port_index); 40 | } 41 | 42 | bool HRegionUnionModel::RunTask() 43 | { 44 | PortIndex const outPortIndex = 0; 45 | if (m_InRegion->hRegion() == nullptr) 46 | { 47 | return false; 48 | } 49 | try 50 | { 51 | HalconCpp::Union2(*m_InRegion->hRegion(), *m_InRegionAdd->hRegion(), m_result->hRegion()); 52 | 53 | m_result->setSize(m_InRegion->getSize()); 54 | 55 | modelValidationState = NodeValidationState::Valid; 56 | modelValidationError = QString(); 57 | } 58 | catch (...) 59 | { 60 | modelValidationState = NodeValidationState::Warning; 61 | modelValidationError = QStringLiteral("缺失或运行失败!"); 62 | } 63 | 64 | Q_EMIT dataUpdated(outPortIndex); 65 | 66 | return true; 67 | } 68 | 69 | bool HRegionUnionModel::eventFilter(QObject* watched, QEvent* event) 70 | { 71 | 72 | return false; 73 | } 74 | 75 | unsigned int HRegionUnionModel:: 76 | nPorts(PortType portType) const 77 | { 78 | unsigned int result = 1; 79 | 80 | switch (portType) 81 | { 82 | case PortType::In: 83 | result = 2; 84 | break; 85 | 86 | case PortType::Out: 87 | result = 1; 88 | 89 | default: 90 | break; 91 | } 92 | 93 | return result; 94 | } 95 | 96 | NodeValidationState HRegionUnionModel::validationState() const 97 | { 98 | return modelValidationState; 99 | } 100 | 101 | QString HRegionUnionModel::validationMessage() const 102 | { 103 | return modelValidationError; 104 | } 105 | 106 | NodeDataType 107 | HRegionUnionModel::dataType(PortType, PortIndex) const 108 | { 109 | return HRegionData().type(); 110 | } 111 | 112 | void HRegionUnionModel:: 113 | setInData(std::shared_ptr data, int portIndex) 114 | { 115 | auto hRegionData = 116 | std::dynamic_pointer_cast(data); 117 | if (hRegionData == nullptr) 118 | { 119 | return; 120 | } 121 | switch (portIndex) 122 | { 123 | case 0: 124 | m_InRegion->setHRegion(*hRegionData->hRegion()); 125 | m_InRegion->setSize(hRegionData->getSize()); 126 | break; 127 | case 1: 128 | m_InRegionAdd->setHRegion(*hRegionData->hRegion()); 129 | m_InRegionAdd->setSize(hRegionData->getSize()); 130 | break; 131 | default: 132 | break; 133 | } 134 | RunTask(); 135 | } 136 | 137 | std::shared_ptr 138 | HRegionUnionModel:: 139 | outData(PortIndex index) 140 | { 141 | switch (index) 142 | { 143 | case 0: 144 | return std::dynamic_pointer_cast(m_result); 145 | break; 146 | case 1: 147 | break; 148 | default: 149 | break; 150 | } 151 | return std::dynamic_pointer_cast(m_result); 152 | } 153 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HRegionUnionModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "DataModelRegistry.hpp" 9 | #include "NodeDataModel.hpp" 10 | #include "halconcpp/HalconCpp.h" 11 | #include "HImageData.hpp" 12 | #include "HRegionData.hpp" 13 | #include "HImageViewWidget.hpp" 14 | 15 | using QtNodes::PortType; 16 | using QtNodes::PortIndex; 17 | using QtNodes::NodeData; 18 | using QtNodes::NodeDataType; 19 | using QtNodes::NodeDataModel; 20 | using QtNodes::NodeValidationState; 21 | using namespace HalconCpp; 22 | /** 23 | * \brief halcon 图像rgb2gray节点 24 | */ 25 | class HRegionUnionModel :public NodeDataModel 26 | { 27 | Q_OBJECT 28 | public: 29 | HRegionUnionModel(); 30 | virtual ~HRegionUnionModel() {} 31 | 32 | public: 33 | QString caption() const override 34 | { 35 | return QStringLiteral("联合区域"); 36 | } 37 | QString name() const override 38 | { 39 | return QStringLiteral("联合区域"); 40 | } 41 | virtual QString modelName() const 42 | { 43 | return QStringLiteral("联合区域"); 44 | } 45 | unsigned int 46 | nPorts(PortType portType) const override; 47 | 48 | NodeDataType 49 | dataType(PortType portType, PortIndex portIndex) const override; 50 | 51 | std::shared_ptr 52 | outData(PortIndex port) override; 53 | 54 | void 55 | setInData(std::shared_ptr, int) override; 56 | 57 | QWidget* 58 | embeddedWidget() override { return nullptr; } 59 | 60 | bool 61 | resizable() const override { return true; } 62 | NodeValidationState 63 | validationState() const override; 64 | QString 65 | validationMessage() const override; 66 | bool portCaptionVisible(PortType, PortIndex) const override { return true; } 67 | QString portCaption(PortType, PortIndex) const override; 68 | protected: 69 | bool RunTask(); 70 | bool eventFilter(QObject* watched, QEvent* event) override; 71 | public: 72 | NodeValidationState modelValidationState = NodeValidationState::Warning; 73 | QString modelValidationError = QStringLiteral("区域输入未连接!"); 74 | private: 75 | std::shared_ptr m_InRegion; 76 | std::shared_ptr m_InRegionAdd; 77 | std::shared_ptr m_result; 78 | }; 79 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/halcon/HalconNodes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //halcon nodes 4 | #include "halcon/HImageLoaderModel.hpp" 5 | #include "halcon/HImageFolderModel.hpp" 6 | #include "halcon/HImageShowModel.hpp" 7 | #include "halcon/HImageRGB2GrayModel.hpp" 8 | #include "halcon/HImageThresholdModel.hpp" 9 | #include "halcon/HImageSplitChanelModel.hpp" 10 | #include "halcon/HRegionSelectModel.hpp" 11 | #include "halcon/HRegionConnectModel.hpp" 12 | #include "halcon/HRegionShapeTransModel.hpp" 13 | #include "halcon/HImageReduceDomainModel.hpp" 14 | #include "halcon/HRegionFillUpShapeModel.hpp" 15 | #include "halcon/HRegionOpenCircleModel.hpp" 16 | #include "halcon/HRegionUnionModel.hpp" 17 | #include "halcon/HRegionDifferenceModel.hpp" 18 | #include "halcon/HRegionSelectShapeStdModel.hpp" 19 | #include "halcon/HImageDLSegmentModel.hpp" 20 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/images/ImageLoaderModel.cpp: -------------------------------------------------------------------------------- 1 | #include "ImageLoaderModel.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | ImageLoaderModel:: 8 | ImageLoaderModel() 9 | : _label(new QLabel(QStringLiteral("点击加载图片!"))) 10 | { 11 | //_label->setAlignment(Qt::AlignHCenter); 12 | 13 | QFont f = _label->font(); 14 | f.setBold(true); 15 | f.setItalic(true); 16 | 17 | _label->setFont(f); 18 | 19 | _label->setFixedSize(200, 200); 20 | 21 | _label->installEventFilter(this); 22 | } 23 | 24 | 25 | unsigned int 26 | ImageLoaderModel:: 27 | nPorts(PortType portType) const 28 | { 29 | unsigned int result = 1; 30 | 31 | switch (portType) 32 | { 33 | case PortType::In: 34 | result = 0; 35 | break; 36 | 37 | case PortType::Out: 38 | result = 1; 39 | 40 | default: 41 | break; 42 | } 43 | 44 | return result; 45 | } 46 | 47 | bool 48 | ImageLoaderModel:: 49 | eventFilter(QObject* object, QEvent* event) 50 | { 51 | if (object == _label) 52 | { 53 | int w = _label->width(); 54 | int h = _label->height(); 55 | 56 | if (event->type() == QEvent::MouseButtonPress) 57 | { 58 | 59 | QString fileName = 60 | QFileDialog::getOpenFileName(nullptr, 61 | tr("Open Image"), 62 | QDir::homePath(), 63 | tr("Image Files (*.png *.jpg *.bmp)")); 64 | 65 | _pixmap = QPixmap(fileName); 66 | 67 | _label->setPixmap(_pixmap.scaled(w, h, Qt::KeepAspectRatio)); 68 | 69 | Q_EMIT dataUpdated(0); 70 | 71 | return true; 72 | } 73 | else if (event->type() == QEvent::Resize) 74 | { 75 | if (!_pixmap.isNull()) 76 | _label->setPixmap(_pixmap.scaled(w, h, Qt::KeepAspectRatio)); 77 | } 78 | } 79 | 80 | return false; 81 | } 82 | 83 | 84 | NodeDataType 85 | ImageLoaderModel:: 86 | dataType(PortType, PortIndex) const 87 | { 88 | return PixmapData().type(); 89 | } 90 | 91 | 92 | std::shared_ptr 93 | ImageLoaderModel:: 94 | outData(PortIndex) 95 | { 96 | return std::make_shared(_pixmap); 97 | } 98 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/images/ImageLoaderModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "DataModelRegistry.hpp" 9 | #include "NodeDataModel.hpp" 10 | 11 | #include "PixmapData.hpp" 12 | 13 | using QtNodes::PortType; 14 | using QtNodes::PortIndex; 15 | using QtNodes::NodeData; 16 | using QtNodes::NodeDataType; 17 | using QtNodes::NodeDataModel; 18 | using QtNodes::NodeValidationState; 19 | 20 | /// The model dictates the number of inputs and outputs for the Node. 21 | /// In this example it has no logic. 22 | class ImageLoaderModel : public NodeDataModel 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | ImageLoaderModel(); 28 | 29 | virtual 30 | ~ImageLoaderModel() {} 31 | 32 | public: 33 | 34 | QString 35 | caption() const override 36 | { 37 | return QStringLiteral("QPixmap输入"); 38 | } 39 | 40 | QString 41 | name() const override { return QStringLiteral("QPixmap输入"); } 42 | 43 | public: 44 | 45 | virtual QString 46 | modelName() const 47 | { 48 | return QStringLiteral("QPixmap输入"); 49 | } 50 | 51 | unsigned int 52 | nPorts(PortType portType) const override; 53 | 54 | NodeDataType 55 | dataType(PortType portType, PortIndex portIndex) const override; 56 | 57 | std::shared_ptr 58 | outData(PortIndex port) override; 59 | 60 | void 61 | setInData(std::shared_ptr, int) override 62 | { } 63 | 64 | QWidget* 65 | embeddedWidget() override { return _label; } 66 | 67 | bool 68 | resizable() const override { return true; } 69 | 70 | protected: 71 | 72 | bool 73 | eventFilter(QObject* object, QEvent* event) override; 74 | 75 | private: 76 | 77 | QLabel* _label; 78 | 79 | QPixmap _pixmap; 80 | }; 81 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/images/ImageShowModel.cpp: -------------------------------------------------------------------------------- 1 | #include "ImageShowModel.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "DataModelRegistry.hpp" 9 | 10 | #include "PixmapData.hpp" 11 | 12 | ImageShowModel:: 13 | ImageShowModel() 14 | : _label(new QLabel("Image will appear here")) 15 | { 16 | _label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); 17 | 18 | QFont f = _label->font(); 19 | f.setBold(true); 20 | f.setItalic(true); 21 | 22 | _label->setFont(f); 23 | 24 | _label->setFixedSize(200, 200); 25 | 26 | _label->installEventFilter(this); 27 | } 28 | 29 | unsigned int 30 | ImageShowModel:: 31 | nPorts(PortType portType) const 32 | { 33 | unsigned int result = 1; 34 | 35 | switch (portType) 36 | { 37 | case PortType::In: 38 | result = 1; 39 | break; 40 | 41 | case PortType::Out: 42 | result = 1; 43 | 44 | default: 45 | break; 46 | } 47 | 48 | return result; 49 | } 50 | 51 | 52 | bool 53 | ImageShowModel:: 54 | eventFilter(QObject* object, QEvent* event) 55 | { 56 | if (object == _label) 57 | { 58 | int w = _label->width(); 59 | int h = _label->height(); 60 | 61 | if (event->type() == QEvent::Resize) 62 | { 63 | auto d = std::dynamic_pointer_cast(_nodeData); 64 | if (d) 65 | { 66 | _label->setPixmap(d->pixmap().scaled(w, h, Qt::KeepAspectRatio)); 67 | } 68 | } 69 | } 70 | return false; 71 | } 72 | 73 | NodeDataType 74 | ImageShowModel:: 75 | dataType(PortType, PortIndex) const 76 | { 77 | return PixmapData().type(); 78 | } 79 | 80 | 81 | std::shared_ptr 82 | ImageShowModel:: 83 | outData(PortIndex) 84 | { 85 | return _nodeData; 86 | } 87 | 88 | 89 | void 90 | ImageShowModel:: 91 | setInData(std::shared_ptr nodeData, PortIndex) 92 | { 93 | _nodeData = nodeData; 94 | 95 | if (_nodeData) 96 | { 97 | auto d = std::dynamic_pointer_cast(_nodeData); 98 | 99 | int w = _label->width(); 100 | int h = _label->height(); 101 | 102 | _label->setPixmap(d->pixmap().scaled(w, h, Qt::KeepAspectRatio)); 103 | } 104 | else 105 | { 106 | _label->setPixmap(QPixmap()); 107 | } 108 | 109 | Q_EMIT dataUpdated(0); 110 | } 111 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/images/ImageShowModel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "DataModelRegistry.hpp" 9 | #include "NodeDataModel.hpp" 10 | 11 | using QtNodes::PortType; 12 | using QtNodes::PortIndex; 13 | using QtNodes::NodeData; 14 | using QtNodes::NodeDataType; 15 | using QtNodes::NodeDataModel; 16 | using QtNodes::NodeValidationState; 17 | 18 | /// The model dictates the number of inputs and outputs for the Node. 19 | /// In this example it has no logic. 20 | class ImageShowModel : public NodeDataModel 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | ImageShowModel(); 26 | 27 | virtual 28 | ~ImageShowModel() {} 29 | 30 | public: 31 | 32 | QString 33 | caption() const override 34 | { 35 | return QStringLiteral("QPixmap 显示"); 36 | } 37 | 38 | QString 39 | name() const override 40 | { 41 | return QStringLiteral("QPixmap显示节点"); 42 | } 43 | 44 | public: 45 | 46 | virtual QString 47 | modelName() const 48 | { 49 | return QStringLiteral("QPixmap显示"); 50 | } 51 | 52 | unsigned int 53 | nPorts(PortType portType) const override; 54 | 55 | NodeDataType 56 | dataType(PortType portType, PortIndex portIndex) const override; 57 | 58 | std::shared_ptr 59 | outData(PortIndex port) override; 60 | 61 | void 62 | setInData(std::shared_ptr nodeData, PortIndex port) override; 63 | 64 | QWidget* 65 | embeddedWidget() override { return _label; } 66 | 67 | bool 68 | resizable() const override { return true; } 69 | 70 | protected: 71 | 72 | bool 73 | eventFilter(QObject* object, QEvent* event) override; 74 | 75 | private: 76 | 77 | QLabel* _label; 78 | 79 | std::shared_ptr _nodeData; 80 | }; 81 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/images/PixmapData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "NodeDataModel.hpp" 6 | 7 | using QtNodes::NodeData; 8 | using QtNodes::NodeDataType; 9 | 10 | /// The class can potentially incapsulate any user data which 11 | /// need to be transferred within the Node Editor graph 12 | class PixmapData : public NodeData 13 | { 14 | public: 15 | 16 | PixmapData() {} 17 | 18 | PixmapData(QPixmap const& pixmap) 19 | : _pixmap(pixmap) 20 | {} 21 | 22 | NodeDataType 23 | type() const override 24 | { 25 | // id name 26 | return { "pixmap", "QPixmap" }; 27 | } 28 | 29 | QPixmap 30 | pixmap() const { return _pixmap; } 31 | 32 | private: 33 | 34 | QPixmap _pixmap{}; 35 | }; 36 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/images/VisionFlowWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "VisionFlowWidget.hpp" 2 | 3 | VisionFlowWidget::VisionFlowWidget(QWidget* parent) 4 | { 5 | main_layout = new QVBoxLayout(); 6 | header_layout = new QHBoxLayout(); 7 | btn_load_scheme = new QPushButton("Load"); 8 | btn_save_scheme = new QPushButton("Save"); 9 | btn_clear_scene = new QPushButton("Clear"); 10 | btn_test = new QPushButton("test"); 11 | header_layout->setAlignment(Qt::AlignLeft); 12 | btn_load_scheme->setFixedWidth(120); 13 | btn_save_scheme->setFixedWidth(120); 14 | btn_clear_scene->setFixedWidth(120); 15 | this->setLayout(main_layout); 16 | main_layout->addLayout(header_layout); 17 | header_layout->addWidget(btn_load_scheme); 18 | header_layout->addWidget(btn_save_scheme); 19 | header_layout->addWidget(btn_clear_scene); 20 | header_layout->addWidget(btn_test); 21 | header_layout->setContentsMargins(0, 0, 0, 0); 22 | main_layout->setContentsMargins(1, 1, 1, 1); 23 | main_layout->setSpacing(1); 24 | m_scene = new FlowScene(registerDataModels()); 25 | m_view = new FlowView(m_scene); 26 | main_layout->addWidget(m_view); 27 | this->setWindowTitle(QStringLiteral("节点编辑器")); 28 | this->resize(1280, 1024); 29 | setConnection(); 30 | } 31 | 32 | VisionFlowWidget::~VisionFlowWidget() 33 | { 34 | 35 | } 36 | 37 | void VisionFlowWidget::setConnection() 38 | { 39 | connect(btn_load_scheme, &QPushButton::clicked, [=]() 40 | { 41 | m_scene->load(); 42 | }); 43 | connect(btn_save_scheme, &QPushButton::clicked, [=]() 44 | { 45 | m_scene->save(); 46 | }); 47 | connect(btn_clear_scene, &QPushButton::clicked, [=]() 48 | { 49 | m_scene->clearScene(); 50 | }); 51 | connect(btn_test, &QPushButton::clicked, [=]() 52 | { 53 | DrawShapeView::getInst()->show(); 54 | }); 55 | } 56 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/images/VisionFlowWidget.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NodeData.hpp" 4 | #include "FlowScene.hpp" 5 | #include "FlowView.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "ImageShowModel.hpp" 13 | #include "ImageLoaderModel.hpp" 14 | #include "DrawShapeView.hpp" 15 | #include "halcon/HalconNodes.hpp" 16 | #include "calculator/MathNodes.hpp" 17 | 18 | using QtNodes::DataModelRegistry; 19 | using QtNodes::FlowScene; 20 | using QtNodes::FlowView; 21 | 22 | static std::shared_ptr 23 | registerDataModels() 24 | { 25 | QString numberNodeType = QStringLiteral("数学操作"); 26 | QString imageNodeType = QStringLiteral("图像操作"); 27 | QString getImageNodeType = QStringLiteral("获取图像"); 28 | QString dlNodeType = QStringLiteral("深度学习"); 29 | QString matchNodeType = QStringLiteral("模板匹配"); 30 | auto ret = std::make_shared(); 31 | 32 | //数学节点 33 | ret->registerModel(numberNodeType); 34 | ret->registerModel(numberNodeType); 35 | ret->registerModel(numberNodeType); 36 | ret->registerModel(numberNodeType); 37 | ret->registerModel(numberNodeType); 38 | ret->registerModel(numberNodeType); 39 | //图像获取 40 | ret->registerModel(getImageNodeType); 41 | ret->registerModel(getImageNodeType); 42 | //图像操作 43 | ret->registerModel(imageNodeType); 44 | ret->registerModel(imageNodeType); 45 | ret->registerModel(imageNodeType); 46 | ret->registerModel(imageNodeType); 47 | ret->registerModel(imageNodeType); 48 | ret->registerModel(imageNodeType); 49 | ret->registerModel(imageNodeType); 50 | ret->registerModel(imageNodeType); 51 | ret->registerModel(imageNodeType); 52 | ret->registerModel(imageNodeType); 53 | ret->registerModel(imageNodeType); 54 | ret->registerModel(imageNodeType); 55 | ret->registerModel(imageNodeType); 56 | ret->registerModel(imageNodeType); 57 | 58 | return ret; 59 | } 60 | 61 | class VisionFlowWidget :public QWidget 62 | { 63 | public: 64 | VisionFlowWidget(QWidget* parent = Q_NULLPTR); 65 | virtual ~VisionFlowWidget(); 66 | private: 67 | QVBoxLayout* main_layout; 68 | QHBoxLayout* header_layout; 69 | QPushButton* btn_load_scheme; 70 | QPushButton* btn_save_scheme; 71 | QPushButton* btn_clear_scene; 72 | QPushButton* btn_test; 73 | FlowScene* m_scene; 74 | FlowView* m_view; 75 | //DrawShapeView* m_draw_shape_view; 76 | private: 77 | void setConnection(); 78 | }; 79 | -------------------------------------------------------------------------------- /NodeEditorPro/examples/images/main.cpp: -------------------------------------------------------------------------------- 1 |  2 | #include 3 | #include "VisionFlowWidget.hpp" 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | QApplication app(argc, argv); 8 | app.setWindowIcon(QIcon(":/logo.png")); 9 | VisionFlowWidget* mainWidget = new VisionFlowWidget(); 10 | mainWidget->show(); 11 | 12 | return app.exec(); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /NodeEditorPro/halcon20.11_x64_cpp.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | <_ProjectFileVersion>14.0.25431.1 8 | 9 | 10 | 11 | B:\CodeDeps\halconlibs\include;%(AdditionalIncludeDirectories) 12 | 13 | 14 | halcon.lib;halconcpp.lib;%(AdditionalDependencies) 15 | B:\CodeDeps\halconlibs\libs;%(AdditionalLibraryDirectories) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/Compiler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if \ 4 | defined (__MINGW32__) || \ 5 | defined (__MINGW64__) 6 | # define NODE_EDITOR_COMPILER "MinGW" 7 | # define NODE_EDITOR_COMPILER_MINGW 8 | #elif \ 9 | defined (__GNUC__) 10 | # define NODE_EDITOR_COMPILER "GNU" 11 | # define NODE_EDITOR_COMPILER_GNU 12 | # define NODE_EDITOR_COMPILER_GNU_VERSION_MAJOR __GNUC__ 13 | # define NODE_EDITOR_COMPILER_GNU_VERSION_MINOR __GNUC_MINOR__ 14 | # define NODE_EDITOR_COMPILER_GNU_VERSION_PATCH __GNUC_PATCHLEVEL__ 15 | #elif \ 16 | defined (__clang__) 17 | # define NODE_EDITOR_COMPILER "Clang" 18 | # define NODE_EDITOR_COMPILER_CLANG 19 | #elif \ 20 | defined (_MSC_VER) 21 | # define NODE_EDITOR_COMPILER "Microsoft Visual C++" 22 | # define NODE_EDITOR_COMPILER_MICROSOFT 23 | #elif \ 24 | defined (__BORLANDC__) 25 | # define NODE_EDITOR_COMPILER "Borland C++ Builder" 26 | # define NODE_EDITOR_COMPILER_BORLAND 27 | #elif \ 28 | defined (__CODEGEARC__) 29 | # define NODE_EDITOR_COMPILER "CodeGear C++ Builder" 30 | # define NODE_EDITOR_COMPILER_CODEGEAR 31 | #elif \ 32 | defined (__INTEL_COMPILER) || \ 33 | defined (__ICL) 34 | # define NODE_EDITOR_COMPILER "Intel C++" 35 | # define NODE_EDITOR_COMPILER_INTEL 36 | #elif \ 37 | defined (__xlC__) || \ 38 | defined (__IBMCPP__) 39 | # define NODE_EDITOR_COMPILER "IBM XL C++" 40 | # define NODE_EDITOR_COMPILER_IBM 41 | #elif \ 42 | defined (__HP_aCC) 43 | # define NODE_EDITOR_COMPILER "HP aC++" 44 | # define NODE_EDITOR_COMPILER_HP 45 | #elif \ 46 | defined (__WATCOMC__) 47 | # define NODE_EDITOR_COMPILER "Watcom C++" 48 | # define NODE_EDITOR_COMPILER_WATCOM 49 | #endif 50 | 51 | #ifndef NODE_EDITOR_COMPILER 52 | # error "Current compiler is not supported." 53 | #endif 54 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/Connection.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "PortType.hpp" 8 | #include "NodeData.hpp" 9 | 10 | #include "Serializable.hpp" 11 | #include "ConnectionState.hpp" 12 | #include "ConnectionGeometry.hpp" 13 | #include "TypeConverter.hpp" 14 | #include "QUuidStdHash.hpp" 15 | #include "Export.hpp" 16 | #include "memory.hpp" 17 | 18 | class QPointF; 19 | 20 | namespace QtNodes 21 | { 22 | 23 | class Node; 24 | class NodeData; 25 | class ConnectionGraphicsObject; 26 | 27 | /** 28 | * \brief 节点连接线 29 | */ 30 | class Connection 31 | : public QObject 32 | , public Serializable 33 | { 34 | 35 | Q_OBJECT 36 | 37 | public: 38 | 39 | /// 新的连接对象会连接到目标节点,连接的端口应当有 端口类型,端口序号 40 | /// 连接对象的另一端应当是相反的端口。 41 | Connection(PortType portType, 42 | Node& node, 43 | PortIndex portIndex); 44 | 45 | Connection(Node& nodeIn, 46 | PortIndex portIndexIn, 47 | Node& nodeOut, 48 | PortIndex portIndexOut, 49 | TypeConverter converter = 50 | TypeConverter{}); 51 | 52 | Connection(const Connection&) = delete; 53 | Connection operator=(const Connection&) = delete; 54 | 55 | ~Connection(); 56 | 57 | public: 58 | 59 | QJsonObject 60 | save() const override; 61 | 62 | public: 63 | 64 | QUuid 65 | id() const; 66 | 67 | /// Remembers the end being dragged. 68 | /// Invalidates Node address. 69 | /// Grabs mouse. 70 | void 71 | setRequiredPort(PortType portType); 72 | PortType 73 | requiredPort() const; 74 | 75 | void 76 | setGraphicsObject(std::unique_ptr&& graphics); 77 | 78 | /// Assigns a node to the required port. 79 | /// It is assumed that there is a required port, no extra checks 80 | void 81 | setNodeToPort(Node& node, 82 | PortType portType, 83 | PortIndex portIndex); 84 | 85 | void 86 | removeFromNodes() const; 87 | 88 | public: 89 | 90 | ConnectionGraphicsObject& 91 | getConnectionGraphicsObject() const; 92 | 93 | ConnectionState const& 94 | connectionState() const; 95 | ConnectionState& 96 | connectionState(); 97 | 98 | ConnectionGeometry& 99 | connectionGeometry(); 100 | 101 | ConnectionGeometry const& 102 | connectionGeometry() const; 103 | 104 | Node* 105 | getNode(PortType portType) const; 106 | 107 | Node*& 108 | getNode(PortType portType); 109 | 110 | PortIndex 111 | getPortIndex(PortType portType) const; 112 | 113 | void 114 | clearNode(PortType portType); 115 | 116 | NodeDataType 117 | dataType(PortType portType) const; 118 | 119 | void 120 | setTypeConverter(TypeConverter converter); 121 | 122 | bool 123 | complete() const; 124 | 125 | public: // data propagation 126 | 127 | void 128 | propagateData(std::shared_ptr nodeData) const; 129 | 130 | void 131 | propagateEmptyData() const; 132 | 133 | Q_SIGNALS: 134 | 135 | void 136 | connectionCompleted(Connection const&) const; 137 | 138 | void 139 | connectionMadeIncomplete(Connection const&) const; 140 | 141 | private: 142 | 143 | QUuid _uid; 144 | 145 | private: 146 | 147 | Node* _outNode = nullptr; 148 | Node* _inNode = nullptr; 149 | 150 | PortIndex _outPortIndex; 151 | PortIndex _inPortIndex; 152 | 153 | private: 154 | 155 | ConnectionState _connectionState; 156 | ConnectionGeometry _connectionGeometry; 157 | 158 | std::unique_ptr_connectionGraphicsObject; 159 | 160 | TypeConverter _converter; 161 | 162 | Q_SIGNALS: 163 | 164 | void 165 | updated(Connection& conn) const; 166 | }; 167 | } 168 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/ConnectionGeometry.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PortType.hpp" 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace QtNodes 11 | { 12 | 13 | class ConnectionGeometry 14 | { 15 | public: 16 | 17 | ConnectionGeometry(); 18 | 19 | public: 20 | 21 | QPointF const& 22 | getEndPoint(PortType portType) const; 23 | 24 | void 25 | setEndPoint(PortType portType, QPointF const& point); 26 | 27 | void 28 | moveEndPoint(PortType portType, QPointF const& offset); 29 | 30 | QRectF 31 | boundingRect() const; 32 | 33 | std::pair 34 | pointsC1C2() const; 35 | 36 | QPointF 37 | source() const { return _out; } 38 | QPointF 39 | sink() const { return _in; } 40 | 41 | double 42 | lineWidth() const { return _lineWidth; } 43 | 44 | bool 45 | hovered() const { return _hovered; } 46 | void 47 | setHovered(bool hovered) { _hovered = hovered; } 48 | 49 | private: 50 | // local object coordinates 51 | QPointF _in; 52 | QPointF _out; 53 | 54 | //int _animationPhase; 55 | 56 | double _lineWidth; 57 | 58 | bool _hovered; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/ConnectionGraphicsObject.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | class QGraphicsSceneMouseEvent; 8 | 9 | namespace QtNodes 10 | { 11 | 12 | class FlowScene; 13 | class Connection; 14 | class ConnectionGeometry; 15 | class Node; 16 | 17 | /// Graphic Object for connection. Adds itself to scene 18 | class ConnectionGraphicsObject 19 | : public QGraphicsObject 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | 25 | ConnectionGraphicsObject(FlowScene& scene, 26 | Connection& connection); 27 | 28 | virtual 29 | ~ConnectionGraphicsObject(); 30 | 31 | enum { Type = UserType + 2 }; 32 | int 33 | type() const override { return Type; } 34 | 35 | public: 36 | 37 | Connection& 38 | connection(); 39 | 40 | QRectF 41 | boundingRect() const override; 42 | 43 | QPainterPath 44 | shape() const override; 45 | 46 | void 47 | setGeometryChanged(); 48 | 49 | /// Updates the position of both ends 50 | void 51 | move(); 52 | 53 | void 54 | lock(bool locked); 55 | 56 | protected: 57 | 58 | void 59 | paint(QPainter* painter, 60 | QStyleOptionGraphicsItem const* option, 61 | QWidget* widget = 0) override; 62 | 63 | void 64 | mousePressEvent(QGraphicsSceneMouseEvent* event) override; 65 | 66 | void 67 | mouseMoveEvent(QGraphicsSceneMouseEvent* event) override; 68 | 69 | void 70 | mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override; 71 | 72 | void 73 | hoverEnterEvent(QGraphicsSceneHoverEvent* event) override; 74 | 75 | void 76 | hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override; 77 | 78 | private: 79 | 80 | void 81 | addGraphicsEffect(); 82 | 83 | private: 84 | 85 | FlowScene& _scene; 86 | 87 | Connection& _connection; 88 | }; 89 | } 90 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/ConnectionState.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "PortType.hpp" 6 | 7 | class QPointF; 8 | 9 | namespace QtNodes 10 | { 11 | 12 | class Node; 13 | 14 | /// Stores currently draggind end. 15 | /// Remembers last hovered Node. 16 | class ConnectionState 17 | { 18 | public: 19 | 20 | ConnectionState(PortType port = PortType::None) 21 | : _requiredPort(port) 22 | {} 23 | 24 | ConnectionState(const ConnectionState&) = delete; 25 | ConnectionState operator=(const ConnectionState&) = delete; 26 | 27 | ~ConnectionState(); 28 | 29 | public: 30 | 31 | void setRequiredPort(PortType end) 32 | { 33 | _requiredPort = end; 34 | } 35 | 36 | PortType requiredPort() const 37 | { 38 | return _requiredPort; 39 | } 40 | 41 | bool requiresPort() const 42 | { 43 | return _requiredPort != PortType::None; 44 | } 45 | 46 | void setNoRequiredPort() 47 | { 48 | _requiredPort = PortType::None; 49 | } 50 | 51 | public: 52 | 53 | void interactWithNode(Node* node); 54 | 55 | void setLastHoveredNode(Node* node); 56 | 57 | Node* 58 | lastHoveredNode() const 59 | { 60 | return _lastHoveredNode; 61 | } 62 | 63 | void resetLastHoveredNode(); 64 | 65 | private: 66 | 67 | PortType _requiredPort; 68 | 69 | Node* _lastHoveredNode{ nullptr }; 70 | }; 71 | } 72 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/ConnectionStyle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Export.hpp" 6 | #include "Style.hpp" 7 | 8 | namespace QtNodes 9 | { 10 | 11 | class ConnectionStyle : public Style 12 | { 13 | public: 14 | 15 | ConnectionStyle(); 16 | 17 | ConnectionStyle(QString jsonText); 18 | 19 | public: 20 | 21 | static void setConnectionStyle(QString fileName); 22 | 23 | private: 24 | 25 | void loadJsonFile(QString fileName) override; 26 | 27 | void saveJsonFile(QString fileName) override; 28 | 29 | public: 30 | 31 | QColor constructionColor() const; 32 | QColor normalColor() const; 33 | QColor normalColor(QString typeId) const; 34 | QColor selectedColor() const; 35 | QColor selectedHaloColor() const; 36 | QColor hoveredColor() const; 37 | 38 | float lineWidth() const; 39 | float constructionLineWidth() const; 40 | float pointDiameter() const; 41 | 42 | bool useDataDefinedColors() const; 43 | 44 | public: 45 | 46 | QColor ConstructionColor; 47 | QColor NormalColor; 48 | QColor SelectedColor; 49 | QColor SelectedHaloColor; 50 | QColor HoveredColor; 51 | 52 | float LineWidth; 53 | float ConstructionLineWidth; 54 | float PointDiameter; 55 | 56 | bool UseDataDefinedColors; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/Export.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Compiler.hpp" 4 | #include "OperatingSystem.hpp" 5 | 6 | #ifdef NODE_EDITOR_PLATFORM_WINDOWS 7 | # define NODE_EDITOR_EXPORT __declspec(dllexport) 8 | # define NODE_EDITOR_IMPORT __declspec(dllimport) 9 | # define NODE_EDITOR_LOCAL 10 | #elif \ 11 | NODE_EDITOR_COMPILER_GNU_VERSION_MAJOR >= 4 || \ 12 | defined (NODE_EDITOR_COMPILER_CLANG) 13 | # define NODE_EDITOR_EXPORT __attribute__((visibility("default"))) 14 | # define NODE_EDITOR_IMPORT __attribute__((visibility("default"))) 15 | # define NODE_EDITOR_LOCAL __attribute__((visibility("hidden"))) 16 | #else 17 | # define NODE_EDITOR_EXPORT 18 | # define NODE_EDITOR_IMPORT 19 | # define NODE_EDITOR_LOCAL 20 | #endif 21 | 22 | #ifdef __cplusplus 23 | # define NODE_EDITOR_DEMANGLED extern "C" 24 | #else 25 | # define NODE_EDITOR_DEMANGLED 26 | #endif 27 | 28 | 29 | //#if defined (NODE_EDITOR_SHARED) && !defined (NODE_EDITOR_STATIC) 30 | //# ifdef NODE_EDITOR_EXPORTS 31 | //# define NODE_EDITOR_EXPORT 32 | //# else 33 | //# define NODE_EDITOR_IMPORT 34 | //# endif 35 | //# define NODE_EDITOR_PRIVATE NODE_EDITOR_LOCAL 36 | //#elif !defined (NODE_EDITOR_SHARED) && defined (NODE_EDITOR_STATIC) 37 | //# define 38 | //# define NODE_EDITOR_PRIVATE 39 | //#elif defined (NODE_EDITOR_SHARED) && defined (NODE_EDITOR_STATIC) 40 | //# ifdef NODE_EDITOR_EXPORTS 41 | //# error "Cannot build as shared and static simultaneously." 42 | //# else 43 | //# error "Cannot link against shared and static simultaneously." 44 | //# endif 45 | //#else 46 | //# ifdef NODE_EDITOR_EXPORTS 47 | //# error "Choose whether to build as shared or static." 48 | //# else 49 | //# error "Choose whether to link against shared or static." 50 | //# endif 51 | //#endif 52 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/FlowView.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Export.hpp" 6 | 7 | namespace QtNodes 8 | { 9 | 10 | class FlowScene; 11 | 12 | class FlowView 13 | : public QGraphicsView 14 | { 15 | Q_OBJECT 16 | public: 17 | 18 | FlowView(QWidget* parent = Q_NULLPTR); 19 | FlowView(FlowScene* scene, QWidget* parent = Q_NULLPTR); 20 | 21 | FlowView(const FlowView&) = delete; 22 | FlowView operator=(const FlowView&) = delete; 23 | 24 | QAction* clearSelectionAction() const; 25 | 26 | QAction* deleteSelectionAction() const; 27 | 28 | void setScene(FlowScene* scene); 29 | 30 | public Q_SLOTS: 31 | 32 | void scaleUp(); 33 | 34 | void scaleDown(); 35 | 36 | void deleteSelectedNodes(); 37 | 38 | protected: 39 | 40 | void contextMenuEvent(QContextMenuEvent* event) override; 41 | 42 | void wheelEvent(QWheelEvent* event) override; 43 | 44 | void keyPressEvent(QKeyEvent* event) override; 45 | 46 | void keyReleaseEvent(QKeyEvent* event) override; 47 | 48 | void mousePressEvent(QMouseEvent* event) override; 49 | 50 | void mouseMoveEvent(QMouseEvent* event) override; 51 | 52 | void mouseReleaseEvent(QMouseEvent* event) override; 53 | 54 | void drawBackground(QPainter* painter, const QRectF& r) override; 55 | 56 | void showEvent(QShowEvent* event) override; 57 | 58 | protected: 59 | 60 | FlowScene* scene(); 61 | 62 | private: 63 | 64 | QAction* _clearSelectionAction; 65 | QAction* _deleteSelectionAction; 66 | 67 | QPointF _clickPos; 68 | 69 | FlowScene* _scene; 70 | }; 71 | } 72 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/FlowViewStyle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Export.hpp" 6 | #include "Style.hpp" 7 | 8 | namespace QtNodes 9 | { 10 | 11 | class FlowViewStyle : public Style 12 | { 13 | public: 14 | 15 | FlowViewStyle(); 16 | 17 | FlowViewStyle(QString jsonText); 18 | 19 | public: 20 | 21 | static void setStyle(QString jsonText); 22 | 23 | private: 24 | 25 | 26 | void loadJsonFile(QString fileName) override; 27 | void saveJsonFile(QString fileName) override; 28 | 29 | public: 30 | 31 | QColor BackgroundColor; 32 | QColor FineGridColor; 33 | QColor CoarseGridColor; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/Node.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "PortType.hpp" 10 | 11 | #include "Export.hpp" 12 | #include "NodeState.hpp" 13 | #include "NodeGeometry.hpp" 14 | #include "NodeData.hpp" 15 | #include "NodeGraphicsObject.hpp" 16 | #include "ConnectionGraphicsObject.hpp" 17 | #include "Serializable.hpp" 18 | #include "memory.hpp" 19 | 20 | namespace QtNodes 21 | { 22 | 23 | class Connection; 24 | class ConnectionState; 25 | class NodeGraphicsObject; 26 | class NodeDataModel; 27 | 28 | class Node 29 | : public QObject 30 | , public Serializable 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | 36 | /// NodeDataModel should be an rvalue and is moved into the Node 37 | Node(std::unique_ptr&& dataModel); 38 | 39 | virtual 40 | ~Node(); 41 | 42 | public: 43 | /** 44 | * \brief Json序列化 45 | * \return json object 46 | */ 47 | QJsonObject 48 | save() const override; 49 | /** 50 | * \brief Json反序列化 51 | * \param json json 52 | */ 53 | void 54 | restore(QJsonObject const& json) override; 55 | 56 | public: 57 | /** 58 | * \brief 节点的QUuid 59 | * \return uid 60 | */ 61 | QUuid 62 | id() const; 63 | 64 | void reactToPossibleConnection(PortType, 65 | NodeDataType const&, 66 | QPointF const& scenePoint); 67 | 68 | void 69 | resetReactionToConnection(); 70 | 71 | public: 72 | 73 | NodeGraphicsObject const& 74 | nodeGraphicsObject() const; 75 | 76 | NodeGraphicsObject& 77 | nodeGraphicsObject(); 78 | 79 | void 80 | setGraphicsObject(std::unique_ptr&& graphics); 81 | 82 | NodeGeometry& 83 | nodeGeometry(); 84 | 85 | NodeGeometry const& 86 | nodeGeometry() const; 87 | 88 | NodeState const& 89 | nodeState() const; 90 | 91 | NodeState& 92 | nodeState(); 93 | 94 | NodeDataModel* 95 | nodeDataModel() const; 96 | 97 | public Q_SLOTS: // data propagation 98 | 99 | /// Propagates incoming data to the underlying model. 100 | void 101 | propagateData(std::shared_ptr nodeData, 102 | PortIndex inPortIndex, 103 | const QUuid& connectionId) const; 104 | 105 | /// Fetches data from model's OUT #index port 106 | /// and propagates it to the connection 107 | void 108 | onDataUpdated(PortIndex index); 109 | 110 | /// Propagates empty data to the attached connection. 111 | void 112 | onDataInvalidated(PortIndex index); 113 | 114 | /// update the graphic part if the size of the embeddedwidget changes 115 | void 116 | onNodeSizeUpdated(); 117 | 118 | private: 119 | 120 | // addressing 121 | QUuid _uid; 122 | 123 | // data 124 | std::unique_ptr _nodeDataModel; 125 | 126 | NodeState _nodeState; 127 | 128 | // painting 129 | NodeGeometry _nodeGeometry; 130 | 131 | std::unique_ptr _nodeGraphicsObject; 132 | }; 133 | } 134 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/NodeData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Export.hpp" 6 | 7 | namespace QtNodes 8 | { 9 | 10 | struct NodeDataType 11 | { 12 | QString id; 13 | /** 14 | * \brief 用于比较的名称 15 | */ 16 | QString name; 17 | 18 | friend bool operator<(QtNodes::NodeDataType const& d1, 19 | QtNodes::NodeDataType const& d2) 20 | { 21 | return d1.id < d2.id; 22 | } 23 | 24 | friend bool operator==(const QtNodes::NodeDataType& d1, 25 | const QtNodes::NodeDataType& d2) noexcept 26 | { 27 | return d1.id == d2.id; 28 | } 29 | }; 30 | 31 | /// Class represents data transferred between nodes. 32 | /// @param type is used for comparing the types 33 | /// The actual data is stored in subtypes 34 | class NodeData 35 | { 36 | public: 37 | 38 | virtual ~NodeData() = default; 39 | 40 | virtual bool sameType(NodeData const& nodeData) const 41 | { 42 | return (this->type().id == nodeData.type().id); 43 | } 44 | 45 | /** 46 | * \brief 节点标签 47 | * \return 标签名字 48 | */ 49 | virtual NodeDataType type() const = 0; 50 | 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/NodeGeometry.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "PortType.hpp" 9 | #include "Export.hpp" 10 | #include "memory.hpp" 11 | 12 | namespace QtNodes 13 | { 14 | 15 | class NodeState; 16 | class NodeDataModel; 17 | class Node; 18 | 19 | class NodeGeometry 20 | { 21 | public: 22 | 23 | NodeGeometry(std::unique_ptr const& dataModel); 24 | 25 | public: 26 | unsigned int 27 | height() const { return _height; } 28 | 29 | void 30 | setHeight(unsigned int h) { _height = h; } 31 | 32 | unsigned int 33 | width() const { return _width; } 34 | 35 | void 36 | setWidth(unsigned int w) { _width = w; } 37 | 38 | unsigned int 39 | entryHeight() const { return _entryHeight; } 40 | void 41 | setEntryHeight(unsigned int h) { _entryHeight = h; } 42 | 43 | unsigned int 44 | entryWidth() const { return _entryWidth; } 45 | 46 | void 47 | setEntryWidth(unsigned int w) { _entryWidth = w; } 48 | 49 | unsigned int 50 | spacing() const { return _spacing; } 51 | 52 | void 53 | setSpacing(unsigned int s) { _spacing = s; } 54 | 55 | bool 56 | hovered() const { return _hovered; } 57 | 58 | void 59 | setHovered(unsigned int h) { _hovered = h; } 60 | 61 | unsigned int 62 | nSources() const; 63 | 64 | unsigned int 65 | nSinks() const; 66 | 67 | QPointF const& 68 | draggingPos() const 69 | { 70 | return _draggingPos; 71 | } 72 | 73 | void 74 | setDraggingPosition(QPointF const& pos) 75 | { 76 | _draggingPos = pos; 77 | } 78 | 79 | public: 80 | 81 | QRectF 82 | entryBoundingRect() const; 83 | 84 | QRectF 85 | boundingRect() const; 86 | 87 | /// Updates size unconditionally 88 | void 89 | recalculateSize() const; 90 | 91 | /// Updates size if the QFontMetrics is changed 92 | void 93 | recalculateSize(QFont const& font) const; 94 | 95 | // TODO removed default QTransform() 96 | QPointF 97 | portScenePosition(PortIndex index, 98 | PortType portType, 99 | QTransform const& t = QTransform()) const; 100 | 101 | PortIndex 102 | checkHitScenePoint(PortType portType, 103 | QPointF point, 104 | QTransform const& t = QTransform()) const; 105 | 106 | QRect 107 | resizeRect() const; 108 | 109 | /// Returns the position of a widget on the Node surface 110 | QPointF 111 | widgetPosition() const; 112 | 113 | /// Returns the maximum height a widget can be without causing the node to grow. 114 | int 115 | equivalentWidgetHeight() const; 116 | 117 | unsigned int 118 | validationHeight() const; 119 | 120 | unsigned int 121 | validationWidth() const; 122 | 123 | static 124 | QPointF 125 | calculateNodePositionBetweenNodePorts(PortIndex targetPortIndex, PortType targetPort, Node* targetNode, 126 | PortIndex sourcePortIndex, PortType sourcePort, Node* sourceNode, 127 | Node& newNode); 128 | private: 129 | 130 | unsigned int 131 | captionHeight() const; 132 | 133 | unsigned int 134 | captionWidth() const; 135 | 136 | unsigned int 137 | portWidth(PortType portType) const; 138 | 139 | private: 140 | 141 | // some variables are mutable because 142 | // we need to change drawing metrics 143 | // corresponding to fontMetrics 144 | // but this doesn't change constness of Node 145 | 146 | mutable unsigned int _width; 147 | mutable unsigned int _height; 148 | unsigned int _entryWidth; 149 | mutable unsigned int _inputPortWidth; 150 | mutable unsigned int _outputPortWidth; 151 | mutable unsigned int _entryHeight; 152 | unsigned int _spacing; 153 | 154 | bool _hovered; 155 | 156 | unsigned int _nSources; 157 | unsigned int _nSinks; 158 | 159 | QPointF _draggingPos; 160 | 161 | std::unique_ptr const& _dataModel; 162 | 163 | mutable QFontMetrics _fontMetrics; 164 | mutable QFontMetrics _boldFontMetrics; 165 | }; 166 | } 167 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/NodeGraphicsObject.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Connection.hpp" 7 | 8 | #include "NodeGeometry.hpp" 9 | #include "NodeState.hpp" 10 | 11 | class QGraphicsProxyWidget; 12 | 13 | namespace QtNodes 14 | { 15 | 16 | class FlowScene; 17 | class FlowItemEntry; 18 | 19 | /// Class reacts on GUI events, mouse clicks and 20 | /// forwards painting operation. 21 | class NodeGraphicsObject : public QGraphicsObject 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | NodeGraphicsObject(FlowScene& scene, 27 | Node& node); 28 | 29 | virtual 30 | ~NodeGraphicsObject(); 31 | 32 | Node& 33 | node(); 34 | 35 | Node const& 36 | node() const; 37 | 38 | QRectF 39 | boundingRect() const override; 40 | 41 | void 42 | setGeometryChanged(); 43 | 44 | /// Visits all attached connections and corrects 45 | /// their corresponding end points. 46 | void 47 | moveConnections() const; 48 | 49 | enum { Type = UserType + 1 }; 50 | 51 | int 52 | type() const override { return Type; } 53 | 54 | void 55 | lock(bool locked); 56 | 57 | protected: 58 | void 59 | paint(QPainter* painter, 60 | QStyleOptionGraphicsItem const* option, 61 | QWidget* widget = 0) override; 62 | 63 | QVariant 64 | itemChange(GraphicsItemChange change, const QVariant& value) override; 65 | 66 | void 67 | mousePressEvent(QGraphicsSceneMouseEvent* event) override; 68 | 69 | void 70 | mouseMoveEvent(QGraphicsSceneMouseEvent* event) override; 71 | 72 | void 73 | mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override; 74 | 75 | void 76 | hoverEnterEvent(QGraphicsSceneHoverEvent* event) override; 77 | 78 | void 79 | hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override; 80 | 81 | void 82 | hoverMoveEvent(QGraphicsSceneHoverEvent*) override; 83 | 84 | void 85 | mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) override; 86 | 87 | void 88 | contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override; 89 | 90 | private: 91 | 92 | void 93 | embedQWidget(); 94 | 95 | private: 96 | 97 | FlowScene& _scene; 98 | 99 | Node& _node; 100 | 101 | bool _locked; 102 | 103 | // either nullptr or owned by parent QGraphicsItem 104 | QGraphicsProxyWidget* _proxyWidget; 105 | }; 106 | } 107 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/NodePainterDelegate.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "NodeGeometry.hpp" 6 | #include "NodeDataModel.hpp" 7 | #include "Export.hpp" 8 | 9 | namespace QtNodes { 10 | 11 | /// Class to allow for custom painting 12 | class NodePainterDelegate 13 | { 14 | 15 | public: 16 | 17 | virtual 18 | ~NodePainterDelegate() = default; 19 | 20 | virtual void 21 | paint(QPainter* painter, 22 | NodeGeometry const& geom, 23 | NodeDataModel const* model) = 0; 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/NodeState.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "Export.hpp" 9 | 10 | #include "PortType.hpp" 11 | #include "NodeData.hpp" 12 | #include "memory.hpp" 13 | 14 | namespace QtNodes 15 | { 16 | 17 | class Connection; 18 | class NodeDataModel; 19 | 20 | /// Contains vectors of connected input and output connections. 21 | /// Stores bool for reacting on hovering connections 22 | class NodeState 23 | { 24 | public: 25 | enum ReactToConnectionState 26 | { 27 | REACTING, 28 | NOT_REACTING 29 | }; 30 | 31 | public: 32 | 33 | NodeState(std::unique_ptr const& model); 34 | 35 | public: 36 | 37 | using ConnectionPtrSet = 38 | std::unordered_map; 39 | 40 | /// Returns vector of connections ID. 41 | /// Some of them can be empty (null) 42 | std::vector const& 43 | getEntries(PortType) const; 44 | 45 | std::vector& 46 | getEntries(PortType); 47 | 48 | ConnectionPtrSet 49 | connections(PortType portType, PortIndex portIndex) const; 50 | 51 | void 52 | setConnection(PortType portType, 53 | PortIndex portIndex, 54 | Connection& connection); 55 | 56 | void 57 | eraseConnection(PortType portType, 58 | PortIndex portIndex, 59 | QUuid id); 60 | 61 | ReactToConnectionState 62 | reaction() const; 63 | 64 | PortType 65 | reactingPortType() const; 66 | 67 | NodeDataType 68 | reactingDataType() const; 69 | 70 | void 71 | setReaction(ReactToConnectionState reaction, 72 | PortType reactingPortType = PortType::None, 73 | 74 | NodeDataType reactingDataType = 75 | NodeDataType()); 76 | 77 | bool 78 | isReacting() const; 79 | 80 | void 81 | setResizing(bool resizing); 82 | 83 | bool 84 | resizing() const; 85 | 86 | private: 87 | 88 | std::vector _inConnections; 89 | std::vector _outConnections; 90 | 91 | ReactToConnectionState _reaction; 92 | PortType _reactingPortType; 93 | NodeDataType _reactingDataType; 94 | 95 | bool _resizing; 96 | }; 97 | } 98 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/NodeStyle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Export.hpp" 6 | #include "Style.hpp" 7 | 8 | namespace QtNodes 9 | { 10 | 11 | class NodeStyle : public Style 12 | { 13 | public: 14 | 15 | NodeStyle(); 16 | 17 | NodeStyle(QString jsonText); 18 | 19 | public: 20 | 21 | static void setNodeStyle(QString fileName); 22 | 23 | private: 24 | 25 | void loadJsonFile(QString fileName) override; 26 | void saveJsonFile(QString fileName) override; 27 | 28 | public: 29 | 30 | QColor NormalBoundaryColor; 31 | QColor SelectedBoundaryColor; 32 | QColor BackgroundColor; 33 | QColor TitleColor; 34 | QColor GradientColor0; 35 | QColor GradientColor1; 36 | QColor GradientColor2; 37 | QColor GradientColor3; 38 | QColor ShadowColor; 39 | QColor FontColor; 40 | QColor FontColorFaded; 41 | 42 | QColor ConnectionPointColor; 43 | QColor FilledConnectionPointColor; 44 | 45 | QColor WarningColor; 46 | QColor ErrorColor; 47 | 48 | float PenWidth; 49 | float HoveredPenWidth; 50 | 51 | float ConnectionPointDiameter; 52 | 53 | float Opacity; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/PortType.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace QtNodes 7 | { 8 | 9 | enum class PortType 10 | { 11 | None, 12 | In, 13 | Out 14 | }; 15 | 16 | static const int INVALID = -1; 17 | 18 | using PortIndex = int; 19 | 20 | struct Port 21 | { 22 | PortType type; 23 | 24 | PortIndex index; 25 | 26 | Port() 27 | : type(PortType::None) 28 | , index(INVALID) 29 | {} 30 | 31 | Port(PortType t, PortIndex i) 32 | : type(t) 33 | , index(i) 34 | {} 35 | 36 | bool 37 | indexIsValid() { return index != INVALID; } 38 | 39 | bool 40 | portTypeIsValid() { return type != PortType::None; } 41 | }; 42 | 43 | //using PortAddress = std::pair; 44 | 45 | inline 46 | PortType 47 | oppositePort(PortType port) 48 | { 49 | PortType result = PortType::None; 50 | 51 | switch (port) 52 | { 53 | case PortType::In: 54 | result = PortType::Out; 55 | break; 56 | 57 | case PortType::Out: 58 | result = PortType::In; 59 | break; 60 | 61 | default: 62 | break; 63 | } 64 | 65 | return result; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/QStringStdHash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) 6 | 7 | // As of 5.14 there is a specialization std::hash 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace std 15 | { 16 | template<> 17 | struct hash 18 | { 19 | inline std::size_t 20 | operator()(QString const& s) const 21 | { 22 | return qHash(s); 23 | } 24 | }; 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/QUuidStdHash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace std 9 | { 10 | template<> 11 | struct hash 12 | { 13 | inline 14 | std::size_t 15 | operator()(QUuid const& uid) const 16 | { 17 | return qHash(uid); 18 | } 19 | }; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/Serializable.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace QtNodes 6 | { 7 | 8 | class Serializable 9 | { 10 | public: 11 | 12 | virtual 13 | ~Serializable() = default; 14 | 15 | virtual 16 | QJsonObject 17 | save() const = 0; 18 | 19 | virtual void 20 | restore(QJsonObject const& /*p*/) {} 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/Style.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace QtNodes 6 | { 7 | 8 | class Style 9 | { 10 | public: 11 | 12 | virtual 13 | ~Style() = default; 14 | 15 | private: 16 | 17 | virtual void 18 | loadJsonFile(QString fileName) = 0; 19 | virtual void 20 | saveJsonFile(QString fileName) = 0; 21 | }; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/StyleCollection.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NodeStyle.hpp" 4 | #include "ConnectionStyle.hpp" 5 | #include "FlowViewStyle.hpp" 6 | #include "Export.hpp" 7 | 8 | namespace QtNodes 9 | { 10 | 11 | class StyleCollection 12 | { 13 | public: 14 | 15 | static 16 | NodeStyle const& 17 | nodeStyle(); 18 | 19 | static 20 | ConnectionStyle const& 21 | connectionStyle(); 22 | 23 | static 24 | FlowViewStyle const& 25 | flowViewStyle(); 26 | 27 | public: 28 | 29 | static 30 | void 31 | setNodeStyle(NodeStyle); 32 | 33 | static 34 | void 35 | setConnectionStyle(ConnectionStyle); 36 | 37 | static 38 | void 39 | setFlowViewStyle(FlowViewStyle); 40 | 41 | private: 42 | 43 | StyleCollection() = default; 44 | 45 | StyleCollection(StyleCollection const&) = delete; 46 | 47 | StyleCollection& 48 | operator=(StyleCollection const&) = delete; 49 | 50 | static 51 | StyleCollection& 52 | instance(); 53 | 54 | private: 55 | 56 | NodeStyle _nodeStyle; 57 | 58 | ConnectionStyle _connectionStyle; 59 | 60 | FlowViewStyle _flowViewStyle; 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/TypeConverter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NodeData.hpp" 4 | #include "memory.hpp" 5 | 6 | #include 7 | 8 | namespace QtNodes 9 | { 10 | 11 | using SharedNodeData = std::shared_ptr; 12 | 13 | // a function taking in NodeData and returning NodeData 14 | using TypeConverter = 15 | std::function; 16 | 17 | // data-type-in, data-type-out 18 | using TypeConverterId = 19 | std::pair; 20 | 21 | struct TypeConverterIdHash 22 | { 23 | std::size_t operator()(const QtNodes::TypeConverterId& converter) const noexcept 24 | { 25 | return qHash(converter.first.id) 26 | ^ qHash(converter.second.id); 27 | } 28 | }; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /NodeEditorPro/include/nodes/memory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace QtNodes 7 | { 8 | namespace detail { 9 | #if (!defined(_MSC_VER) && (__cplusplus < 201300)) || \ 10 | ( defined(_MSC_VER) && (_MSC_VER < 1800)) 11 | //_MSC_VER == 1800 is Visual Studio 2013, which is already somewhat C++14 compilant, 12 | // and it has make_unique in it's standard library implementation 13 | template 14 | std::unique_ptr make_unique(Args&&... args) 15 | { 16 | return std::unique_ptr(new T(std::forward(args)...)); 17 | } 18 | #else 19 | template 20 | std::unique_ptr make_unique(Args&&... args) 21 | { 22 | return std::make_unique(std::forward(args)...); 23 | } 24 | #endif 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NodeEditorPro/resources/DefaultStyle - 副本.json: -------------------------------------------------------------------------------- 1 | { 2 | "FlowViewStyle": { 3 | "BackgroundColor": [ 53, 53, 53 ], 4 | "FineGridColor": [ 60, 60, 60 ], 5 | "CoarseGridColor": [ 25, 25, 25 ] 6 | }, 7 | "NodeStyle": { 8 | "NormalBoundaryColor": [ 255, 255, 255 ], 9 | "SelectedBoundaryColor": [ 255, 165, 0 ], 10 | "BackgroundColor": [ 34, 34, 34 ], 11 | "TitleColor": [ 253, 204, 82 ], 12 | "GradientColor0": "gray", 13 | "GradientColor1": [ 80, 80, 80 ], 14 | "GradientColor2": [ 64, 64, 64 ], 15 | "GradientColor3": [ 58, 58, 58 ], 16 | "ShadowColor": [ 20, 20, 20 ], 17 | "FontColor": "white", 18 | "FontColorFaded": "gray", 19 | "ConnectionPointColor": [ 169, 169, 169 ], 20 | "FilledConnectionPointColor": "cyan", 21 | "ErrorColor": "red", 22 | "WarningColor": [ 128, 128, 0 ], 23 | 24 | "PenWidth": 1.0, 25 | "HoveredPenWidth": 1.5, 26 | 27 | "ConnectionPointDiameter": 8.0, 28 | 29 | "Opacity": 0.8 30 | }, 31 | "ConnectionStyle": { 32 | "ConstructionColor": "gray", 33 | "NormalColor": "darkcyan", 34 | "SelectedColor": [ 100, 100, 100 ], 35 | "SelectedHaloColor": "orange", 36 | "HoveredColor": "lightcyan", 37 | 38 | "LineWidth": 3.0, 39 | "ConstructionLineWidth": 2.0, 40 | "PointDiameter": 10.0, 41 | 42 | "UseDataDefinedColors": false 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /NodeEditorPro/resources/DefaultStyle.json: -------------------------------------------------------------------------------- 1 | { 2 | "FlowViewStyle": { 3 | "BackgroundColor": [ 53, 53, 53 ], 4 | "FineGridColor": [ 60, 60, 60 ], 5 | "CoarseGridColor": [ 25, 25, 25 ] 6 | }, 7 | "NodeStyle": { 8 | "NormalBoundaryColor": [ 255, 255, 255 ], 9 | "SelectedBoundaryColor": [ 255, 165, 0 ], 10 | "BackgroundColor": [ 34, 34, 34 ], 11 | "TitleColor": [ 253, 204, 82 ], 12 | "GradientColor0": "gray", 13 | "GradientColor1": [ 80, 80, 80 ], 14 | "GradientColor2": [ 64, 64, 64 ], 15 | "GradientColor3": [ 58, 58, 58 ], 16 | "ShadowColor": [ 20, 20, 20 ], 17 | "FontColor": "white", 18 | "FontColorFaded": "gray", 19 | "ConnectionPointColor": [ 169, 169, 169 ], 20 | "FilledConnectionPointColor": "cyan", 21 | "ErrorColor": "red", 22 | "WarningColor": [ 128, 128, 0 ], 23 | 24 | "PenWidth": 1.0, 25 | "HoveredPenWidth": 1.5, 26 | 27 | "ConnectionPointDiameter": 8.0, 28 | 29 | "Opacity": 0.8 30 | }, 31 | "ConnectionStyle": { 32 | "ConstructionColor": "gray", 33 | "NormalColor": "darkcyan", 34 | "SelectedColor": [ 100, 100, 100 ], 35 | "SelectedHaloColor": "orange", 36 | "HoveredColor": "lightcyan", 37 | 38 | "LineWidth": 3.0, 39 | "ConstructionLineWidth": 2.0, 40 | "PointDiameter": 10.0, 41 | 42 | "UseDataDefinedColors": false 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /NodeEditorPro/resources/convert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/resources/convert.png -------------------------------------------------------------------------------- /NodeEditorPro/resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/resources/logo.png -------------------------------------------------------------------------------- /NodeEditorPro/resources/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | DefaultStyle.json 4 | convert.png 5 | logo.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /NodeEditorPro/showcase/ReduceDomain.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/ReduceDomain.gif -------------------------------------------------------------------------------- /NodeEditorPro/showcase/ReduceDomain.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/ReduceDomain.mp4 -------------------------------------------------------------------------------- /NodeEditorPro/showcase/draw_shape_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/draw_shape_view.png -------------------------------------------------------------------------------- /NodeEditorPro/showcase/reduceNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/reduceNode.png -------------------------------------------------------------------------------- /NodeEditorPro/showcase/selectBallTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/selectBallTest.png -------------------------------------------------------------------------------- /NodeEditorPro/showcase/selectRegionNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/selectRegionNode.png -------------------------------------------------------------------------------- /NodeEditorPro/showcase/showcase1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/showcase1.gif -------------------------------------------------------------------------------- /NodeEditorPro/showcase/showcase2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/showcase2.mp4 -------------------------------------------------------------------------------- /NodeEditorPro/showcase/showcase3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/showcase3.gif -------------------------------------------------------------------------------- /NodeEditorPro/showcase/showcase4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/showcase4.gif -------------------------------------------------------------------------------- /NodeEditorPro/showcase/showcase5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/showcase5.png -------------------------------------------------------------------------------- /NodeEditorPro/showcase/showcase6.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/showcase/showcase6.mp4 -------------------------------------------------------------------------------- /NodeEditorPro/src/ConnectionBlurEffect.cpp: -------------------------------------------------------------------------------- 1 | #include "ConnectionBlurEffect.hpp" 2 | 3 | #include "ConnectionGraphicsObject.hpp" 4 | #include "ConnectionPainter.hpp" 5 | 6 | using QtNodes::ConnectionBlurEffect; 7 | using QtNodes::ConnectionGraphicsObject; 8 | 9 | ConnectionBlurEffect:: 10 | ConnectionBlurEffect(ConnectionGraphicsObject*) 11 | { 12 | // 13 | } 14 | 15 | 16 | void 17 | ConnectionBlurEffect:: 18 | draw(QPainter* painter) 19 | { 20 | QGraphicsBlurEffect::draw(painter); 21 | 22 | //ConnectionPainter::paint(painter, 23 | //_object->connectionGeometry(), 24 | //_object->connectionState()); 25 | 26 | //_item->paint(painter, nullptr, nullptr); 27 | } 28 | -------------------------------------------------------------------------------- /NodeEditorPro/src/ConnectionBlurEffect.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | namespace QtNodes 6 | { 7 | 8 | class ConnectionGraphicsObject; 9 | 10 | class ConnectionBlurEffect : public QGraphicsBlurEffect 11 | { 12 | 13 | public: 14 | 15 | ConnectionBlurEffect(ConnectionGraphicsObject* item); 16 | 17 | void 18 | draw(QPainter* painter) override; 19 | 20 | private: 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /NodeEditorPro/src/ConnectionGeometry.cpp: -------------------------------------------------------------------------------- 1 | #include "ConnectionGeometry.hpp" 2 | 3 | #include 4 | 5 | #include "StyleCollection.hpp" 6 | 7 | using QtNodes::ConnectionGeometry; 8 | using QtNodes::PortType; 9 | 10 | ConnectionGeometry:: 11 | ConnectionGeometry() 12 | : _in(0, 0) 13 | , _out(0, 0) 14 | //, _animationPhase(0) 15 | , _lineWidth(3.0) 16 | , _hovered(false) 17 | { } 18 | 19 | QPointF const& 20 | ConnectionGeometry:: 21 | getEndPoint(PortType portType) const 22 | { 23 | Q_ASSERT(portType != PortType::None); 24 | 25 | return (portType == PortType::Out ? 26 | _out : 27 | _in); 28 | } 29 | 30 | 31 | void 32 | ConnectionGeometry:: 33 | setEndPoint(PortType portType, QPointF const& point) 34 | { 35 | switch (portType) 36 | { 37 | case PortType::Out: 38 | _out = point; 39 | break; 40 | 41 | case PortType::In: 42 | _in = point; 43 | break; 44 | 45 | default: 46 | break; 47 | } 48 | } 49 | 50 | 51 | void 52 | ConnectionGeometry:: 53 | moveEndPoint(PortType portType, QPointF const& offset) 54 | { 55 | switch (portType) 56 | { 57 | case PortType::Out: 58 | _out += offset; 59 | break; 60 | 61 | case PortType::In: 62 | _in += offset; 63 | break; 64 | 65 | default: 66 | break; 67 | } 68 | } 69 | 70 | 71 | QRectF 72 | ConnectionGeometry:: 73 | boundingRect() const 74 | { 75 | auto points = pointsC1C2(); 76 | 77 | QRectF basicRect = QRectF(_out, _in).normalized(); 78 | 79 | QRectF c1c2Rect = QRectF(points.first, points.second).normalized(); 80 | 81 | auto const& connectionStyle = 82 | StyleCollection::connectionStyle(); 83 | 84 | float const diam = connectionStyle.pointDiameter(); 85 | 86 | QRectF commonRect = basicRect.united(c1c2Rect); 87 | 88 | QPointF const cornerOffset(diam, diam); 89 | 90 | commonRect.setTopLeft(commonRect.topLeft() - cornerOffset); 91 | commonRect.setBottomRight(commonRect.bottomRight() + 2 * cornerOffset); 92 | 93 | return commonRect; 94 | } 95 | 96 | 97 | std::pair 98 | ConnectionGeometry:: 99 | pointsC1C2() const 100 | { 101 | const double defaultOffset = 200; 102 | 103 | double xDistance = _in.x() - _out.x(); 104 | 105 | double horizontalOffset = qMin(defaultOffset, std::abs(xDistance)); 106 | 107 | double verticalOffset = 0; 108 | 109 | double ratioX = 0.5; 110 | 111 | if (xDistance <= 0) 112 | { 113 | double yDistance = _in.y() - _out.y() + 20; 114 | 115 | double vector = yDistance < 0 ? -1.0 : 1.0; 116 | 117 | verticalOffset = qMin(defaultOffset, std::abs(yDistance)) * vector; 118 | 119 | ratioX = 1.0; 120 | } 121 | 122 | horizontalOffset *= ratioX; 123 | 124 | QPointF c1(_out.x() + horizontalOffset, 125 | _out.y() + verticalOffset); 126 | 127 | QPointF c2(_in.x() - horizontalOffset, 128 | _in.y() - verticalOffset); 129 | 130 | return std::make_pair(c1, c2); 131 | } 132 | -------------------------------------------------------------------------------- /NodeEditorPro/src/ConnectionPainter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace QtNodes 6 | { 7 | 8 | class ConnectionGeometry; 9 | class ConnectionState; 10 | class Connection; 11 | 12 | class ConnectionPainter 13 | { 14 | public: 15 | 16 | static 17 | void 18 | paint(QPainter* painter, 19 | Connection const& connection); 20 | 21 | static 22 | QPainterPath 23 | getPainterStroke(ConnectionGeometry const& geom); 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /NodeEditorPro/src/ConnectionState.cpp: -------------------------------------------------------------------------------- 1 | #include "ConnectionState.hpp" 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "FlowScene.hpp" 8 | #include "Node.hpp" 9 | 10 | using QtNodes::ConnectionState; 11 | using QtNodes::Node; 12 | 13 | ConnectionState:: 14 | ~ConnectionState() 15 | { 16 | resetLastHoveredNode(); 17 | } 18 | 19 | 20 | void 21 | ConnectionState:: 22 | interactWithNode(Node* node) 23 | { 24 | if (node) 25 | { 26 | _lastHoveredNode = node; 27 | } 28 | else 29 | { 30 | resetLastHoveredNode(); 31 | } 32 | } 33 | 34 | 35 | void 36 | ConnectionState:: 37 | setLastHoveredNode(Node* node) 38 | { 39 | _lastHoveredNode = node; 40 | } 41 | 42 | 43 | void 44 | ConnectionState:: 45 | resetLastHoveredNode() 46 | { 47 | if (_lastHoveredNode) 48 | _lastHoveredNode->resetReactionToConnection(); 49 | 50 | _lastHoveredNode = nullptr; 51 | } 52 | -------------------------------------------------------------------------------- /NodeEditorPro/src/ConnectionStyle.cpp: -------------------------------------------------------------------------------- 1 | #include "ConnectionStyle.hpp" 2 | 3 | #include "StyleCollection.hpp" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | #include "QJsonParser.hpp" 15 | 16 | using QtNodes::ConnectionStyle; 17 | 18 | inline void initResources() { Q_INIT_RESOURCE(resources); } 19 | 20 | ConnectionStyle:: 21 | ConnectionStyle() : 22 | ConstructionColor(20, 20, 20, 255), 23 | NormalColor(0, 139, 139, 255), 24 | SelectedColor(100, 100, 100, 255), 25 | SelectedHaloColor(255, 165, 0, 255), 26 | HoveredColor(225, 255, 255, 255), 27 | LineWidth(3.0), 28 | ConstructionLineWidth(2.0), 29 | PointDiameter(10.0), 30 | UseDataDefinedColors(false) 31 | { 32 | // This configuration is stored inside the compiled unit and is loaded statically 33 | loadJsonFile("DefaultStyle.json"); 34 | } 35 | 36 | 37 | ConnectionStyle:: 38 | ConnectionStyle(QString fileName) 39 | { 40 | loadJsonFile(fileName); 41 | } 42 | 43 | 44 | void 45 | ConnectionStyle:: 46 | setConnectionStyle(QString jsonText) 47 | { 48 | ConnectionStyle style(jsonText); 49 | 50 | StyleCollection::setConnectionStyle(style); 51 | } 52 | 53 | void 54 | ConnectionStyle:: 55 | loadJsonFile(QString styleFile) 56 | { 57 | QJsonObject obj = QJsonConvert::readJsonObj(styleFile); 58 | QJsonObject styleObj = obj["ConnectionStyle"].toObject(); 59 | if (styleObj.isEmpty()) 60 | { 61 | saveJsonFile(styleFile); 62 | } 63 | else 64 | { 65 | QJsonConvert::convertFromJson(obj["ConnectionStyle"].toObject(), *this); 66 | } 67 | } 68 | 69 | void ConnectionStyle::saveJsonFile(QString fileName) 70 | { 71 | QJsonObject obj = QJsonConvert::readJsonObj(fileName); 72 | obj.insert("ConnectionStyle", QJsonConvert::convertToJson(*this)); 73 | QJsonConvert::writeJsonObj(fileName, obj); 74 | } 75 | 76 | QColor 77 | ConnectionStyle:: 78 | constructionColor() const 79 | { 80 | return ConstructionColor; 81 | } 82 | 83 | 84 | QColor 85 | ConnectionStyle:: 86 | normalColor() const 87 | { 88 | return NormalColor; 89 | } 90 | 91 | 92 | QColor 93 | ConnectionStyle:: 94 | normalColor(QString typeId) const 95 | { 96 | std::size_t hash = qHash(typeId); 97 | 98 | std::size_t const hue_range = 0xFF; 99 | 100 | std::mt19937 gen(static_cast(hash)); 101 | std::uniform_int_distribution distrib(0, hue_range); 102 | 103 | int hue = distrib(gen); 104 | int sat = 120 + hash % 129; 105 | 106 | return QColor::fromHsl(hue, 107 | sat, 108 | 160); 109 | } 110 | 111 | 112 | QColor 113 | ConnectionStyle:: 114 | selectedColor() const 115 | { 116 | return SelectedColor; 117 | } 118 | 119 | 120 | QColor 121 | ConnectionStyle:: 122 | selectedHaloColor() const 123 | { 124 | return SelectedHaloColor; 125 | } 126 | 127 | 128 | QColor 129 | ConnectionStyle:: 130 | hoveredColor() const 131 | { 132 | return HoveredColor; 133 | } 134 | 135 | 136 | float 137 | ConnectionStyle:: 138 | lineWidth() const 139 | { 140 | return LineWidth; 141 | } 142 | 143 | 144 | float 145 | ConnectionStyle:: 146 | constructionLineWidth() const 147 | { 148 | return ConstructionLineWidth; 149 | } 150 | 151 | 152 | float 153 | ConnectionStyle:: 154 | pointDiameter() const 155 | { 156 | return PointDiameter; 157 | } 158 | 159 | 160 | bool 161 | ConnectionStyle:: 162 | useDataDefinedColors() const 163 | { 164 | return UseDataDefinedColors; 165 | } 166 | -------------------------------------------------------------------------------- /NodeEditorPro/src/DataModelRegistry.cpp: -------------------------------------------------------------------------------- 1 | #include "DataModelRegistry.hpp" 2 | 3 | #include 4 | #include 5 | 6 | using QtNodes::DataModelRegistry; 7 | using QtNodes::NodeDataModel; 8 | using QtNodes::NodeDataType; 9 | using QtNodes::TypeConverter; 10 | 11 | std::unique_ptr 12 | DataModelRegistry:: 13 | create(QString const& modelName) 14 | { 15 | auto it = _registeredItemCreators.find(modelName); 16 | 17 | if (it != _registeredItemCreators.end()) 18 | { 19 | return it->second(); 20 | } 21 | 22 | return nullptr; 23 | } 24 | 25 | 26 | DataModelRegistry::RegisteredModelCreatorsMap const& 27 | DataModelRegistry:: 28 | registeredModelCreators() const 29 | { 30 | return _registeredItemCreators; 31 | } 32 | 33 | 34 | DataModelRegistry::RegisteredModelsCategoryMap const& 35 | DataModelRegistry:: 36 | registeredModelsCategoryAssociation() const 37 | { 38 | return _registeredModelsCategory; 39 | } 40 | 41 | 42 | DataModelRegistry::CategoriesSet const& 43 | DataModelRegistry:: 44 | categories() const 45 | { 46 | return _categories; 47 | } 48 | 49 | 50 | TypeConverter 51 | DataModelRegistry:: 52 | getTypeConverter(NodeDataType const& d1, 53 | NodeDataType const& d2) const 54 | { 55 | TypeConverterId converterId = std::make_pair(d1, d2); 56 | 57 | auto it = _registeredTypeConverters.find(converterId); 58 | 59 | if (it != _registeredTypeConverters.end()) 60 | { 61 | return it->second; 62 | } 63 | 64 | return TypeConverter{}; 65 | } 66 | -------------------------------------------------------------------------------- /NodeEditorPro/src/FlowViewStyle.cpp: -------------------------------------------------------------------------------- 1 | #include "FlowViewStyle.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "StyleCollection.hpp" 12 | #include "QJsonParser.hpp" 13 | 14 | using QtNodes::FlowViewStyle; 15 | 16 | inline void initResources() { Q_INIT_RESOURCE(resources); } 17 | 18 | FlowViewStyle:: 19 | FlowViewStyle() : 20 | BackgroundColor(53, 53, 53, 255), 21 | FineGridColor(60, 60, 60, 255), 22 | CoarseGridColor(25, 25, 25, 255) 23 | { 24 | loadJsonFile("DefaultStyle.json"); 25 | } 26 | 27 | 28 | FlowViewStyle:: 29 | FlowViewStyle(QString jsonText) 30 | { 31 | loadJsonFile(jsonText); 32 | } 33 | 34 | 35 | void 36 | FlowViewStyle:: 37 | setStyle(QString jsonText) 38 | { 39 | FlowViewStyle style(jsonText); 40 | 41 | StyleCollection::setFlowViewStyle(style); 42 | } 43 | 44 | void 45 | FlowViewStyle:: 46 | loadJsonFile(QString styleFile) 47 | { 48 | QJsonObject obj = QJsonConvert::readJsonObj(styleFile); 49 | QJsonObject styleObj = obj["FlowViewStyle"].toObject(); 50 | if (styleObj.isEmpty()) 51 | { 52 | saveJsonFile(styleFile); 53 | } 54 | else 55 | { 56 | QJsonConvert::convertFromJson(obj["FlowViewStyle"].toObject(), *this); 57 | } 58 | } 59 | 60 | void QtNodes::FlowViewStyle::saveJsonFile(QString fileName) 61 | { 62 | QJsonObject obj = QJsonConvert::readJsonObj(fileName); 63 | obj.insert("FlowViewStyle", QJsonConvert::convertToJson(*this)); 64 | QJsonConvert::writeJsonObj(fileName, obj); 65 | } 66 | 67 | -------------------------------------------------------------------------------- /NodeEditorPro/src/NodeConnectionInteraction.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Node.hpp" 4 | #include "Connection.hpp" 5 | 6 | namespace QtNodes 7 | { 8 | 9 | class DataModelRegistry; 10 | class FlowScene; 11 | class NodeDataModel; 12 | 13 | /// Class performs various operations on the Node and Connection pair. 14 | /// An instance should be created on the stack and destroyed when 15 | /// the operation is completed 16 | class NodeConnectionInteraction 17 | { 18 | public: 19 | NodeConnectionInteraction(Node& node, 20 | Connection& connection, 21 | FlowScene& scene); 22 | 23 | /// Can connect when following conditions are met: 24 | /// 1) Connection 'requires' a port 25 | /// 2) Connection's vacant end is above the node port 26 | /// 3) Node port is vacant 27 | /// 4) Connection type equals node port type, or there is a registered type conversion that can translate between the two 28 | bool canConnect(PortIndex& portIndex, 29 | TypeConverter& converter) const; 30 | 31 | /// 1) Check conditions from 'canConnect' 32 | /// 1.5) If the connection is possible but a type conversion is needed, add a converter node to the scene, and connect it properly 33 | /// 2) Assign node to required port in Connection 34 | /// 3) Assign Connection to empty port in NodeState 35 | /// 4) Adjust Connection geometry 36 | /// 5) Poke model to initiate data transfer 37 | bool tryConnect() const; 38 | 39 | 40 | /// 1) Node and Connection should be already connected 41 | /// 2) If so, clear Connection entry in the NodeState 42 | /// 3) Propagate invalid data to IN node 43 | /// 4) Set Connection end to 'requiring a port' 44 | bool disconnect(PortType portToDisconnect) const; 45 | 46 | private: 47 | 48 | PortType connectionRequiredPort() const; 49 | 50 | QPointF connectionEndScenePosition(PortType) const; 51 | 52 | QPointF nodePortScenePosition(PortType portType, 53 | PortIndex portIndex) const; 54 | 55 | PortIndex nodePortIndexUnderScenePoint(PortType portType, 56 | QPointF const& p) const; 57 | 58 | bool nodePortIsEmpty(PortType portType, PortIndex portIndex) const; 59 | 60 | private: 61 | 62 | Node* _node; 63 | 64 | Connection* _connection; 65 | 66 | FlowScene* _scene; 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /NodeEditorPro/src/NodeDataModel.cpp: -------------------------------------------------------------------------------- 1 | #include "NodeDataModel.hpp" 2 | 3 | #include "StyleCollection.hpp" 4 | 5 | using QtNodes::NodeDataModel; 6 | using QtNodes::NodeStyle; 7 | 8 | NodeDataModel:: 9 | NodeDataModel() 10 | : _nodeStyle(StyleCollection::nodeStyle()) 11 | { 12 | // Derived classes can initialize specific style here 13 | } 14 | 15 | 16 | QJsonObject 17 | NodeDataModel:: 18 | save() const 19 | { 20 | QJsonObject modelJson; 21 | 22 | modelJson["name"] = name(); 23 | 24 | return modelJson; 25 | } 26 | 27 | 28 | NodeStyle const& 29 | NodeDataModel:: 30 | nodeStyle() const 31 | { 32 | return _nodeStyle; 33 | } 34 | 35 | 36 | void 37 | NodeDataModel:: 38 | setNodeStyle(NodeStyle const& style) 39 | { 40 | _nodeStyle = style; 41 | } 42 | -------------------------------------------------------------------------------- /NodeEditorPro/src/NodePainter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace QtNodes 6 | { 7 | 8 | class Node; 9 | class NodeState; 10 | class NodeGeometry; 11 | class NodeGraphicsObject; 12 | class NodeDataModel; 13 | class FlowItemEntry; 14 | class FlowScene; 15 | 16 | class NodePainter 17 | { 18 | public: 19 | 20 | NodePainter(); 21 | 22 | public: 23 | 24 | static 25 | void 26 | paint(QPainter* painter, 27 | Node& node, 28 | FlowScene const& scene); 29 | 30 | static 31 | void 32 | drawNodeRect(QPainter* painter, 33 | NodeGeometry const& geom, 34 | NodeDataModel const* model, 35 | NodeGraphicsObject const& graphicsObject); 36 | 37 | static 38 | void 39 | drawModelName(QPainter* painter, 40 | NodeGeometry const& geom, 41 | NodeState const& state, 42 | NodeDataModel const* model); 43 | 44 | static 45 | void 46 | drawEntryLabels(QPainter* painter, 47 | NodeGeometry const& geom, 48 | NodeState const& state, 49 | NodeDataModel const* model); 50 | 51 | static 52 | void 53 | drawConnectionPoints(QPainter* painter, 54 | NodeGeometry const& geom, 55 | NodeState const& state, 56 | NodeDataModel const* model, 57 | FlowScene const& scene); 58 | 59 | static 60 | void 61 | drawFilledConnectionPoints(QPainter* painter, 62 | NodeGeometry const& geom, 63 | NodeState const& state, 64 | NodeDataModel const* model); 65 | 66 | static 67 | void 68 | drawResizeRect(QPainter* painter, 69 | NodeGeometry const& geom, 70 | NodeDataModel const* model); 71 | 72 | static 73 | void 74 | drawValidationRect(QPainter* painter, 75 | NodeGeometry const& geom, 76 | NodeDataModel const* model, 77 | NodeGraphicsObject const& graphicsObject); 78 | }; 79 | } 80 | -------------------------------------------------------------------------------- /NodeEditorPro/src/NodeState.cpp: -------------------------------------------------------------------------------- 1 | #include "NodeState.hpp" 2 | 3 | #include "NodeDataModel.hpp" 4 | 5 | #include "Connection.hpp" 6 | 7 | using QtNodes::NodeState; 8 | using QtNodes::NodeDataType; 9 | using QtNodes::NodeDataModel; 10 | using QtNodes::PortType; 11 | using QtNodes::PortIndex; 12 | using QtNodes::Connection; 13 | 14 | NodeState:: 15 | NodeState(std::unique_ptr const& model) 16 | : _inConnections(model->nPorts(PortType::In)) 17 | , _outConnections(model->nPorts(PortType::Out)) 18 | , _reaction(NOT_REACTING) 19 | , _reactingPortType(PortType::None) 20 | , _resizing(false) 21 | {} 22 | 23 | 24 | std::vector const& 25 | NodeState:: 26 | getEntries(PortType portType) const 27 | { 28 | if (portType == PortType::In) 29 | return _inConnections; 30 | else 31 | return _outConnections; 32 | } 33 | 34 | 35 | std::vector& 36 | NodeState:: 37 | getEntries(PortType portType) 38 | { 39 | if (portType == PortType::In) 40 | return _inConnections; 41 | else 42 | return _outConnections; 43 | } 44 | 45 | 46 | NodeState::ConnectionPtrSet 47 | NodeState:: 48 | connections(PortType portType, PortIndex portIndex) const 49 | { 50 | auto const& connections = getEntries(portType); 51 | 52 | return connections[portIndex]; 53 | } 54 | 55 | 56 | void 57 | NodeState:: 58 | setConnection(PortType portType, 59 | PortIndex portIndex, 60 | Connection& connection) 61 | { 62 | auto& connections = getEntries(portType); 63 | 64 | connections.at(portIndex).insert(std::make_pair(connection.id(), 65 | &connection)); 66 | } 67 | 68 | 69 | void 70 | NodeState:: 71 | eraseConnection(PortType portType, 72 | PortIndex portIndex, 73 | QUuid id) 74 | { 75 | getEntries(portType)[portIndex].erase(id); 76 | } 77 | 78 | 79 | NodeState::ReactToConnectionState 80 | NodeState:: 81 | reaction() const 82 | { 83 | return _reaction; 84 | } 85 | 86 | 87 | PortType 88 | NodeState:: 89 | reactingPortType() const 90 | { 91 | return _reactingPortType; 92 | } 93 | 94 | 95 | NodeDataType 96 | NodeState:: 97 | reactingDataType() const 98 | { 99 | return _reactingDataType; 100 | } 101 | 102 | 103 | void 104 | NodeState:: 105 | setReaction(ReactToConnectionState reaction, 106 | PortType reactingPortType, 107 | NodeDataType reactingDataType) 108 | { 109 | _reaction = reaction; 110 | 111 | _reactingPortType = reactingPortType; 112 | 113 | _reactingDataType = std::move(reactingDataType); 114 | } 115 | 116 | 117 | bool 118 | NodeState:: 119 | isReacting() const 120 | { 121 | return _reaction == REACTING; 122 | } 123 | 124 | 125 | void 126 | NodeState:: 127 | setResizing(bool resizing) 128 | { 129 | _resizing = resizing; 130 | } 131 | 132 | 133 | bool 134 | NodeState:: 135 | resizing() const 136 | { 137 | return _resizing; 138 | } 139 | -------------------------------------------------------------------------------- /NodeEditorPro/src/NodeStyle.cpp: -------------------------------------------------------------------------------- 1 | #include "NodeStyle.hpp" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "StyleCollection.hpp" 12 | #include "QJsonParser.hpp" 13 | 14 | using QtNodes::NodeStyle; 15 | 16 | inline void initResources() { Q_INIT_RESOURCE(resources); } 17 | 18 | NodeStyle:: 19 | NodeStyle() : 20 | NormalBoundaryColor(255, 255, 255, 255), 21 | SelectedBoundaryColor(255, 165, 0, 255), 22 | BackgroundColor(34, 34, 34, 255), 23 | TitleColor(253, 204, 82, 255), 24 | GradientColor0(60, 60, 60, 255), 25 | GradientColor1(80, 80, 80, 255), 26 | GradientColor2(64, 64, 64, 255), 27 | GradientColor3(58, 58, 58, 255), 28 | ShadowColor(20, 20, 20, 255), 29 | FontColor(255, 255, 255, 255), 30 | FontColorFaded(120, 120, 120, 255), 31 | ConnectionPointColor(169, 169, 169, 255), 32 | FilledConnectionPointColor(0, 255, 255, 255), 33 | WarningColor(128, 128, 0, 255), 34 | ErrorColor(255, 0, 0, 255), 35 | PenWidth(1.0), 36 | HoveredPenWidth(1.5), 37 | ConnectionPointDiameter(8.0), 38 | Opacity(0.8) 39 | { 40 | // This configuration is stored inside the compiled unit and is loaded statically 41 | loadJsonFile("DefaultStyle.json"); 42 | } 43 | 44 | NodeStyle:: 45 | NodeStyle(QString fileName) 46 | { 47 | loadJsonFile(fileName); 48 | } 49 | 50 | void 51 | NodeStyle:: 52 | setNodeStyle(QString fileName) 53 | { 54 | NodeStyle style(fileName); 55 | StyleCollection::setNodeStyle(style); 56 | } 57 | 58 | void 59 | NodeStyle:: 60 | loadJsonFile(QString styleFile) 61 | { 62 | QJsonObject obj = QJsonConvert::readJsonObj(styleFile); 63 | QJsonObject styleObj = obj["NodeStyle"].toObject(); 64 | if (styleObj.isEmpty()) 65 | { 66 | saveJsonFile(styleFile); 67 | } 68 | else 69 | { 70 | QJsonConvert::convertFromJson(obj["NodeStyle"].toObject(), *this); 71 | } 72 | } 73 | 74 | void QtNodes::NodeStyle::saveJsonFile(QString fileName) 75 | { 76 | QJsonObject obj = QJsonConvert::readJsonObj(fileName); 77 | obj.insert("NodeStyle", QJsonConvert::convertToJson(*this)); 78 | QJsonConvert::writeJsonObj(fileName, obj); 79 | } 80 | -------------------------------------------------------------------------------- /NodeEditorPro/src/Properties.cpp: -------------------------------------------------------------------------------- 1 | #include "Properties.hpp" 2 | 3 | using QtNodes::Properties; 4 | 5 | void 6 | Properties:: 7 | put(QString const& name, QVariant const& v) 8 | { 9 | _values.insert(name, v); 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /NodeEditorPro/src/Properties.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "Export.hpp" 8 | 9 | namespace QtNodes 10 | { 11 | 12 | class Properties 13 | { 14 | public: 15 | 16 | void 17 | put(QString const& name, QVariant const& v); 18 | 19 | template 20 | bool 21 | get(QString name, T* v) const 22 | { 23 | QVariant const& var = _values[name]; 24 | 25 | if (var.canConvert()) 26 | { 27 | *v = _values[name].value(); 28 | 29 | return true; 30 | } 31 | 32 | return false; 33 | } 34 | 35 | QVariantMap const& 36 | values() const 37 | { 38 | return _values; 39 | } 40 | 41 | QVariantMap& 42 | values() 43 | { 44 | return _values; 45 | } 46 | 47 | private: 48 | 49 | QVariantMap _values; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /NodeEditorPro/src/QDataStreamPhaser.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/susigo/VisionFlowPro/ea904d37773624fd672f8c8f2ddd54955afa05bf/NodeEditorPro/src/QDataStreamPhaser.cpp -------------------------------------------------------------------------------- /NodeEditorPro/src/QDataStreamPhaser.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "halconcpp/HalconCpp.h" 6 | 7 | template 8 | inline void loadFromData(const QString _fileName, std::vector& _obj); 9 | 10 | template 11 | inline void saveToData(const QString _fileName, const std::vector& _obj); 12 | 13 | -------------------------------------------------------------------------------- /NodeEditorPro/src/QJsonParser.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "halconcpp/HalconCpp.h" 13 | #include "NodeStyle.hpp" 14 | #include "FlowViewStyle.hpp" 15 | #include "ConnectionStyle.hpp" 16 | #include "DrawShapeView.hpp" 17 | 18 | namespace QJsonConvert 19 | { 20 | 21 | QJsonObject convertToJson(const QVector& obj); 22 | void convertFromJson(const QJsonObject& json, QVector& obj); 23 | 24 | QJsonObject convertToJson(const QVector& obj); 25 | void convertFromJson(const QJsonObject& json, QVector& obj); 26 | 27 | QJsonObject convertToJson(const QVector& obj); 28 | void convertFromJson(const QJsonObject& json, QVector& obj); 29 | 30 | QJsonObject readJsonObj(const QString& fileName); 31 | bool writeJsonObj(const QString& fileName, QJsonObject& json); 32 | 33 | QJsonObject convertToJson(const QPoint& _point); 34 | void convertFromJson(const QJsonObject& _obj, QPoint& _point); 35 | 36 | QJsonObject convertToJson(const QPointF& _point); 37 | void convertFromJson(const QJsonObject& _obj, QPointF& _point); 38 | 39 | QJsonObject convertToJson(const QPolygonF& _polygon); 40 | void convertFromJson(const QJsonObject& _obj, QPolygonF& _polygon); 41 | 42 | QJsonObject convertToJson(const QColor& _color); 43 | void convertFromJson(const QJsonObject& _obj, QColor& _color); 44 | 45 | QJsonObject convertToJson(const QtNodes::NodeStyle& _obj); 46 | void convertFromJson(const QJsonObject& _json, QtNodes::NodeStyle& _obj); 47 | 48 | QJsonObject convertToJson(const QtNodes::FlowViewStyle& _obj); 49 | void convertFromJson(const QJsonObject& _json, QtNodes::FlowViewStyle& _obj); 50 | 51 | QJsonObject convertToJson(const QtNodes::ConnectionStyle& _obj); 52 | void convertFromJson(const QJsonObject& _json, QtNodes::ConnectionStyle& _obj); 53 | 54 | QJsonObject convertToJson(const ShapeDataStruct& _obj); 55 | void convertFromJson(const QJsonObject& _json, ShapeDataStruct& _obj); 56 | 57 | }; 58 | 59 | -------------------------------------------------------------------------------- /NodeEditorPro/src/StyleCollection.cpp: -------------------------------------------------------------------------------- 1 | #include "StyleCollection.hpp" 2 | 3 | using QtNodes::StyleCollection; 4 | using QtNodes::NodeStyle; 5 | using QtNodes::ConnectionStyle; 6 | using QtNodes::FlowViewStyle; 7 | 8 | NodeStyle const& 9 | StyleCollection:: 10 | nodeStyle() 11 | { 12 | return instance()._nodeStyle; 13 | } 14 | 15 | 16 | ConnectionStyle const& 17 | StyleCollection:: 18 | connectionStyle() 19 | { 20 | return instance()._connectionStyle; 21 | } 22 | 23 | 24 | FlowViewStyle const& 25 | StyleCollection:: 26 | flowViewStyle() 27 | { 28 | return instance()._flowViewStyle; 29 | } 30 | 31 | 32 | void 33 | StyleCollection:: 34 | setNodeStyle(NodeStyle nodeStyle) 35 | { 36 | instance()._nodeStyle = nodeStyle; 37 | } 38 | 39 | 40 | void 41 | StyleCollection:: 42 | setConnectionStyle(ConnectionStyle connectionStyle) 43 | { 44 | instance()._connectionStyle = connectionStyle; 45 | } 46 | 47 | 48 | void 49 | StyleCollection:: 50 | setFlowViewStyle(FlowViewStyle flowViewStyle) 51 | { 52 | instance()._flowViewStyle = flowViewStyle; 53 | } 54 | 55 | 56 | 57 | StyleCollection& 58 | StyleCollection:: 59 | instance() 60 | { 61 | static StyleCollection collection; 62 | 63 | return collection; 64 | } 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VisionFlowPro 2 | NodeEditor base on qt halcon c++ ,thanks to this great project https://github.com/paceholder/nodeeditor . I had added some custom feature,and include some halcon nodes. 3 | In the near future i might make it a industrial machine vision software like VisionMaster.finger cross! 4 | by susigo@foxmail.com 5 | 6 | ## 一、项目启发 7 | 自从去年用了海康的VisionMaster后,做一款自己的拖拉拽机器视觉框架的想法就一直萦绕在我心中。所以在后续的时间里我在C#与C++中纠结,接触了大神开源的STNode后,被winform的难搞的绘图方式劝退。Qt有它独特的QGraphicsView框架,图元可以很方便地作为节点进行移动。因为找到的资料很少,恶心的CSDN什么都收费,当时自己摸索做了一个,使用void*指针传值,也可以勉强完成节点间传输数据的任务。后来C++水平提升,终于看懂了大神开源的框架。于是兴奋地通宵上传这个工程。本着开源精神,希望能够抛砖引玉。 8 | 如有指教可联系qq:2576662787 9 | 10 | ## 二、更新日志 11 | *** 12 | 1.更改了绘制图形选区的方式,使用graphicsview。 13 | 14 | ![reducedomain showcase](https://github.com/susigo/VisionFlowPro/blob/master/NodeEditorPro/showcase/draw_shape_view.png) 15 | 16 | *** 17 | 1.完成了一个halcon样例。小demo。 18 | 19 | ![reducedomain showcase](https://github.com/susigo/VisionFlowPro/blob/master/NodeEditorPro/showcase/selectBallTest.png) 20 | 21 | 2022/09/30 22 | *** 23 | 1.更新了选区节点,现在可以坐下一步操作了。如绘制区域训练片训练匹配模型。 24 | 25 | ![reducedomain showcase](https://github.com/susigo/VisionFlowPro/blob/master/NodeEditorPro/showcase/ReduceDomain.gif) 26 | 27 | 2022/09/29 28 | *** 29 | 1. 可以保存项目与读取项目 30 | 2. 添加了SelectRegion的节点、添加了Connection节点。 31 | 32 | ![调通了halcon节点保存的逻辑](https://github.com/susigo/VisionFlowPro/blob/master/NodeEditorPro/showcase/showcase4.gif) 33 | 34 | 2022/09/23 35 | 36 | *** 37 | 38 | -------------------------------------------------------------------------------- /ShapeDrawer/DrawShapeView.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "DrawViewParams.h" 16 | #include "ShapeItemLine.h" 17 | #include "ShapeItemRect1.h" 18 | #include "ShapeItemRect2.h" 19 | #include "ShapeItemPolygon.h" 20 | #include "halconcpp/HalconCpp.h" 21 | 22 | static std::mutex draw_view_lock; 23 | class DrawShapeView :public QGraphicsView 24 | { 25 | Q_OBJECT 26 | public: 27 | 28 | explicit DrawShapeView(QWidget* parent = Q_NULLPTR); 29 | 30 | ~DrawShapeView() {}; 31 | 32 | static DrawShapeView* instance; 33 | 34 | static DrawShapeView* getInst(); 35 | //DrawShapeView(const DrawShapeView&); 36 | DrawShapeView& operator=(const DrawShapeView&); 37 | private: 38 | class Deletor 39 | { 40 | public: 41 | ~Deletor() 42 | { 43 | if (DrawShapeView::instance != nullptr) 44 | { 45 | delete DrawShapeView::instance; 46 | } 47 | } 48 | }; 49 | static Deletor deletor; 50 | private: 51 | QGraphicsScene* m_scene; 52 | QColor m_bg_color = QColor(34, 34, 34, 255); 53 | QColor m_grid_color = QColor(10, 10, 10, 255); 54 | QColor m_hint_bg_color = QColor(0, 255, 0, 100); 55 | QPen m_grid_pen = QPen(m_grid_color, 3); 56 | QString m_hint_str; 57 | QPoint m_cur_pos_view; 58 | QPointF m_cur_pos_scene; 59 | QPointF m_hint_tl; 60 | 61 | ViewMode view_mode = ViewMode::tNone; 62 | EShapeType draw_shape; 63 | ShapeMode shape_mode; 64 | ShapeDataStruct shape_data; 65 | QList shape_items; 66 | ShapeItemBase* cur_shape_item = nullptr; 67 | 68 | QString cur_image_name; 69 | QPixmap m_cur_pixmap; 70 | 71 | QPointF m_lastMousePos; // 鼠标最后按下的位置 72 | QPointF m_centerPos; // 73 | qreal m_scale = 1.0; // 缩放值 74 | 75 | QTransform m_transform; 76 | 77 | QMenu* m_menu; 78 | QGraphicsPixmapItem* m_pixmap_item; 79 | QGraphicsPathItem* m_draw_path_item; 80 | QPolygonF* m_draw_poly; 81 | QPainterPath tmpPath; 82 | 83 | QGraphicsLineItem* v_hint_line; 84 | QGraphicsLineItem* h_hint_line; 85 | 86 | public: 87 | void FitShowImage(const QPixmap& pixmap); 88 | void FitShowImage(const QPixmap& pixmap, ShapeDataStruct& shape_data); 89 | static HalconCpp::HRegion GetHRegionFromData(const ShapeDataStruct& shape_data); 90 | private: 91 | void MenuInit(); 92 | void ParamInit(); 93 | public slots: 94 | void onOpenImage(); 95 | void onFitImageShow(); 96 | void onDrawLineShape(); 97 | void onDrawRectangle1(ShapeMode mode); 98 | void onDrawRectangle2(ShapeMode mode); 99 | void onDrawPolygon(ShapeMode mode); 100 | void onDrawFreeDraw(ShapeMode mode); 101 | void onDrawComform(); 102 | void onDrawCancel(); 103 | signals: 104 | void DrawFinished(); 105 | void RegionComform(ShapeDataStruct shape_data); 106 | private: 107 | void drawFinished(); 108 | void drawHintInfo(QPainter* painter); 109 | void drawCurrentShape(QPainter* painter); 110 | protected: 111 | void mousePressEvent(QMouseEvent* event) override; 112 | 113 | void mouseReleaseEvent(QMouseEvent* event) override; 114 | 115 | void mouseMoveEvent(QMouseEvent* event) override; 116 | 117 | void wheelEvent(QWheelEvent* event) override; 118 | 119 | void paintEvent(QPaintEvent* event) override; 120 | 121 | void drawBackground(QPainter* painter, const QRectF& rect) override; 122 | 123 | }; 124 | 125 | -------------------------------------------------------------------------------- /ShapeDrawer/DrawViewParams.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | enum class ViewMode 5 | { 6 | tNone, 7 | tTranslate, 8 | tZoom, 9 | tDrawing 10 | }; 11 | 12 | enum class EShapeType 13 | { 14 | sNone, 15 | sLine, 16 | sRectangle1Add, 17 | sRectangle2Add, 18 | sPolygonAdd, 19 | sFreeDrawAdd, 20 | sRectangle1Div, 21 | sRectangle2Div, 22 | sPolygonDiv, 23 | sFreeDrawDiv 24 | }; 25 | 26 | enum class ShapeMode 27 | { 28 | mNone, 29 | mAdd, 30 | mDiv 31 | }; 32 | 33 | struct ShapeDataStruct 34 | { 35 | QString name; 36 | QVector shapePolygon; 37 | QVector shapeType; 38 | QVector shapeMode; 39 | }; 40 | 41 | 42 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeControlItem.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeControlItem.h" 2 | #include "ShapeItemBase.h" 3 | 4 | //构造函数 5 | ShapeControlItem::ShapeControlItem(QGraphicsItemGroup* parent, 6 | ControlItemType type, 7 | QPointF p, int style) 8 | : QAbstractGraphicsShapeItem(parent) 9 | { 10 | setPos(p); 11 | setAcceptHoverEvents(true); 12 | handle_type = type; 13 | this->setFlags(QGraphicsItem::ItemIsSelectable | 14 | QGraphicsItem::ItemIsMovable | 15 | QGraphicsItem::ItemIsFocusable); 16 | 17 | bounding_rect = QRectF(-handle_size * 0.5, -handle_size * 0.5, 18 | handle_size, handle_size); 19 | } 20 | 21 | void ShapeControlItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) 22 | { 23 | active_states = true; 24 | Q_UNUSED(event); 25 | } 26 | 27 | void ShapeControlItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) 28 | { 29 | active_states = false; 30 | Q_UNUSED(event); 31 | } 32 | 33 | //拖拽 鼠标感应区域 34 | QRectF ShapeControlItem::boundingRect() const 35 | { 36 | return bounding_rect; //拖拽 鼠标感应区域 37 | } 38 | //位置重绘 39 | void ShapeControlItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 40 | { 41 | painter->setPen(Qt::NoPen); 42 | if (active_states) 43 | { 44 | painter->setBrush(handle_active_color); 45 | bounding_rect = QRectF(-handle_active_size * 0.5, -handle_active_size * 0.5, 46 | handle_active_size, handle_active_size); 47 | } 48 | else 49 | { 50 | painter->setBrush(handle_color); 51 | bounding_rect = QRectF(-handle_size * 0.5, -handle_size * 0.5, 52 | handle_size, handle_size); 53 | } 54 | painter->drawRoundedRect(bounding_rect, 2, 2); 55 | } 56 | //鼠标事件处理 57 | void ShapeControlItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event) 58 | { 59 | if (event->buttons() == Qt::LeftButton) 60 | { 61 | last_point = cur_point; 62 | cur_point = this->mapToParent(event->pos()); 63 | dx = cur_point.x() - last_point.x(); 64 | dy = cur_point.y() - last_point.y(); 65 | if (this->handle_type != cCenter && this->handle_type != cRotate) 66 | { 67 | //结果正常、更新位置 68 | this->setPos(cur_point); 69 | } 70 | } 71 | emit PositionChanged(); 72 | } 73 | 74 | void ShapeControlItem::mousePressEvent(QGraphicsSceneMouseEvent* event) 75 | { 76 | 77 | QGraphicsItem::mousePressEvent(event); 78 | } 79 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeControlItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "DrawViewParams.h" 14 | 15 | enum ControlItemType 16 | { 17 | cNone, 18 | cCenter, 19 | cEdgeNode, 20 | cRotate 21 | }; 22 | 23 | class ShapeControlItem : 24 | public QObject 25 | , public QAbstractGraphicsShapeItem 26 | { 27 | Q_OBJECT 28 | public: 29 | explicit ShapeControlItem(QGraphicsItemGroup* parent, 30 | ControlItemType type, 31 | QPointF p, int style = 1); 32 | ControlItemType getType() { return handle_type; } 33 | qreal getDx() { return dx; } 34 | qreal getDy() { return dy; } 35 | QPointF getCenterPointF() { return this->pos(); } 36 | private: 37 | QRectF bounding_rect; 38 | int handle_size = 5; 39 | int handle_active_size = 8; 40 | bool active_states = false; 41 | QColor handle_color = QColor(255, 255, 0, 100); 42 | QColor handle_active_color = QColor(255, 0, 0, 100); 43 | qreal dx; 44 | qreal dy; 45 | QPointF last_point; 46 | QPointF cur_point; 47 | ControlItemType handle_type; 48 | signals: 49 | void PositionChanged(); 50 | protected: 51 | virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override; 52 | virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override; 53 | virtual QRectF boundingRect() const override; 54 | virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; 55 | virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override; 56 | virtual void mousePressEvent(QGraphicsSceneMouseEvent* event) override; 57 | 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemBase.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeItemBase.h" 2 | 3 | 4 | ShapeItemBase::ShapeItemBase(EShapeType type) :types(type) 5 | { 6 | 7 | setHandlesChildEvents(false);//设置后才能将事件传递到子元素 8 | if (type != EShapeType::sNone) //模式选择 自定义模式用于显示亚像素轮廓和Region 不设定任何属性 9 | { 10 | this->setFlags(QGraphicsItem::ItemIsSelectable | 11 | QGraphicsItem::ItemIsMovable | 12 | QGraphicsItem::ItemIsFocusable); 13 | } 14 | this->setCursor(Qt::ArrowCursor); 15 | activeHandle = nullptr; 16 | bounding_rect = QRectF(0, 0, 100, 100); 17 | ItemPath.addRect(bounding_rect); 18 | ItemShape.addRect(bounding_rect); 19 | } 20 | 21 | ShapeItemBase::~ShapeItemBase() 22 | { 23 | 24 | } 25 | 26 | void ShapeItemBase::focusInEvent(QFocusEvent* event) 27 | { 28 | Q_UNUSED(event); 29 | this->setZValue(99); 30 | shape_active = true; 31 | } 32 | 33 | void ShapeItemBase::focusOutEvent(QFocusEvent* event) 34 | { 35 | Q_UNUSED(event); 36 | this->setZValue(1); 37 | shape_active = false; 38 | } 39 | 40 | QRectF ShapeItemBase::boundingRect() const 41 | { 42 | return ItemPath.boundingRect().united(ItemShape.boundingRect()); 43 | } 44 | 45 | QPainterPath ShapeItemBase::shape() const 46 | { 47 | return ItemShape.united(ItemPath); 48 | } 49 | 50 | void ShapeItemBase::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) 51 | { 52 | QGraphicsItemGroup::paint(painter, option, widget); 53 | painter->setPen(Qt::NoPen); 54 | if (shape_active) 55 | { 56 | painter->setBrush(activeBackgroundColor); 57 | //painter->drawRect(this->boundingRect()); 58 | } 59 | else 60 | { 61 | if (m_shape_mode == ShapeMode::mAdd) 62 | { 63 | painter->setBrush(addBackgroundColor); 64 | } 65 | else 66 | { 67 | painter->setBrush(divBackgroundColor); 68 | } 69 | } 70 | if (!ItemPath.isEmpty()) 71 | { 72 | painter->setPen(ItemColor); 73 | //painter->setBrush(Qt::NoBrush); 74 | painter->drawPath(ItemPath); 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "DrawViewParams.h" 5 | #include "ShapeControlItem.h" 6 | 7 | class ShapeItemBase : 8 | public QObject, public QGraphicsItemGroup 9 | { 10 | Q_OBJECT 11 | public: 12 | ShapeItemBase(EShapeType type); 13 | virtual ~ShapeItemBase(); 14 | void SetZoomVal(qreal ZoomVal) { scaler = ZoomVal; } 15 | qreal GetContrSize() const { return ContrSize; } 16 | QPolygonF GetShapePoygonF() 17 | { 18 | //if (!itemPolygon.isClosed()) 19 | //{ 20 | // itemPolygon.append(itemPolygon.first()); 21 | //} 22 | for (int i = 0; i < itemPolygon.count(); i++) 23 | { 24 | itemPolygon[i] = mapToScene(itemPolygon[i]); 25 | } 26 | return itemPolygon; 27 | } 28 | ShapeMode GetShapeMode() { return m_shape_mode; } 29 | private: 30 | virtual void shapeInit() = 0; 31 | public slots: 32 | virtual void calculateShape() = 0; 33 | virtual void rotateShape(qreal delta) {}; 34 | protected: 35 | void focusInEvent(QFocusEvent* event) override; 36 | 37 | void focusOutEvent(QFocusEvent* event) override; 38 | 39 | QRectF boundingRect() const override; 40 | 41 | QPainterPath shape() const override; 42 | 43 | void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; 44 | 45 | protected: 46 | ShapeControlItem* activeHandle; 47 | QList ControlList; 48 | QRectF bounding_rect; 49 | qreal scaler; //缩放系数 50 | const qreal ContrSize = 8; //控制点尺寸 51 | EShapeType types; //枚举类型 52 | QColor ItemColor = QColor(0, 100, 200); //线条颜色 53 | QColor BackgroundColor = QColor(0, 160, 230, 100); //填充背景颜色 54 | QColor addBackgroundColor = QColor(0, 255, 0, 100); //填充背景颜色 55 | QColor divBackgroundColor = QColor(255, 0, 0, 50); //填充背景颜色 56 | QColor activeBackgroundColor = QColor(255, 255, 0, 100); //填充背景颜色 57 | bool shape_active = false; 58 | QString ItemDiscrib = QString::fromLocal8Bit("描述"); 59 | 60 | ShapeMode m_shape_mode = ShapeMode::mNone; 61 | QPointF Center; //中心点 62 | QPainterPath ItemShape; //有边框区域 63 | QPainterPath ItemPath; //有边框区域 64 | QPolygonF itemPolygon; 65 | }; 66 | 67 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemLine.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeItemLine.h" 2 | 3 | ShapeItemLine::ShapeItemLine(QPointF pos) : 4 | ShapeItemBase(EShapeType::sLine) 5 | { 6 | this->setPos(pos); 7 | shapeInit(); 8 | } 9 | 10 | ShapeItemLine::~ShapeItemLine() 11 | { 12 | } 13 | 14 | void ShapeItemLine::calculateShape() 15 | { 16 | if (this->sender() == nullptr) 17 | { 18 | ControlList[1]->setX(0.5 * (ControlList[0]->x() + ControlList[2]->x())); 19 | ControlList[1]->setY(0.5 * (ControlList[0]->y() + ControlList[2]->y())); 20 | ItemPath.clear(); 21 | itemPolygon[0] = ControlList[0]->getCenterPointF(); 22 | itemPolygon[1] = ControlList[2]->getCenterPointF(); 23 | ItemPath.addPolygon(itemPolygon); 24 | ItemPath.closeSubpath(); 25 | ItemShape.clear(); 26 | ItemShape.addRect(ItemPath.boundingRect()); 27 | } 28 | else 29 | { 30 | activeHandle = dynamic_cast(this->sender()); 31 | 32 | if (activeHandle->getType() == cCenter) 33 | { 34 | //this->moveBy(activeHandle->getDx(), activeHandle->getDy()); 35 | } 36 | else if (activeHandle->getType() == cRotate) 37 | { 38 | 39 | } 40 | else { 41 | 42 | ControlList[1]->setX(0.5 * (ControlList[0]->x() + ControlList[2]->x())); 43 | ControlList[1]->setY(0.5 * (ControlList[0]->y() + ControlList[2]->y())); 44 | ItemPath.clear(); 45 | itemPolygon[0] = ControlList[0]->getCenterPointF(); 46 | itemPolygon[1] = ControlList[2]->getCenterPointF(); 47 | ItemPath.addPolygon(itemPolygon); 48 | ItemPath.closeSubpath(); 49 | ItemShape.clear(); 50 | ItemShape.addRect(ItemPath.boundingRect()); 51 | } 52 | } 53 | } 54 | 55 | void ShapeItemLine::shapeInit() 56 | { 57 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 10))); 58 | ControlList.append(new ShapeControlItem(this, ControlItemType::cCenter, QPointF(50, 50))); 59 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 90))); 60 | itemPolygon.append(QPointF(ControlList[0]->x(), ControlList[0]->y())); 61 | itemPolygon.append(QPointF(ControlList[2]->x(), ControlList[2]->y())); 62 | for (auto elem : ControlList) 63 | { 64 | connect(elem, SIGNAL(PositionChanged()), this, SLOT(calculateShape())); 65 | } 66 | calculateShape(); 67 | } 68 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemLine.h: -------------------------------------------------------------------------------- 1 | #include "ShapeItemBase.h" 2 | 3 | class ShapeItemLine 4 | :public ShapeItemBase 5 | { 6 | public: 7 | ShapeItemLine(QPointF pos = QPointF(0, 0)); 8 | 9 | ~ShapeItemLine(); 10 | private: 11 | void calculateShape() override; 12 | 13 | void shapeInit() override; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemPolygon.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeItemPolygon.h" 2 | 3 | ShapeItemPolygon::ShapeItemPolygon(QPolygonF polygon, ShapeMode shape_mode, QPointF pos) : 4 | ShapeItemBase(EShapeType::sLine) 5 | { 6 | m_shape_mode = shape_mode; 7 | itemPolygon = polygon; 8 | this->setPos(pos); 9 | shapeInit(); 10 | } 11 | 12 | ShapeItemPolygon::~ShapeItemPolygon() 13 | { 14 | } 15 | 16 | void ShapeItemPolygon::calculateShape() 17 | { 18 | if (this->sender() == nullptr) 19 | { 20 | sizeChanged(); 21 | } 22 | else 23 | { 24 | activeHandle = dynamic_cast(this->sender()); 25 | 26 | if (activeHandle->getType() == cCenter) 27 | { 28 | //this->moveBy(activeHandle->getDx(), activeHandle->getDy()); 29 | } 30 | else if (activeHandle->getType() == cRotate) 31 | { 32 | 33 | } 34 | else { 35 | sizeChanged(); 36 | } 37 | } 38 | } 39 | 40 | void ShapeItemPolygon::sizeChanged() 41 | { 42 | ItemPath.clear(); 43 | int i = 0; 44 | for (auto elem : ControlList) 45 | { 46 | itemPolygon[i] = elem->getCenterPointF(); 47 | i++; 48 | } 49 | ItemPath.addPolygon(itemPolygon); 50 | ItemPath.closeSubpath(); 51 | ItemShape.clear(); 52 | ItemShape.addRect(ItemPath.boundingRect()); 53 | } 54 | 55 | void ShapeItemPolygon::shapeInit() 56 | { 57 | for (auto elem : itemPolygon) 58 | { 59 | ControlList.append(new ShapeControlItem(this, cEdgeNode, elem)); 60 | } 61 | for (auto elem : ControlList) 62 | { 63 | connect(elem, SIGNAL(PositionChanged()), this, SLOT(calculateShape())); 64 | } 65 | calculateShape(); 66 | } 67 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemPolygon.h: -------------------------------------------------------------------------------- 1 | #include "ShapeItemBase.h" 2 | 3 | class ShapeItemPolygon 4 | :public ShapeItemBase 5 | { 6 | public: 7 | ShapeItemPolygon(QPolygonF polygon, ShapeMode shape_mode, QPointF pos = QPointF(0, 0)); 8 | 9 | ~ShapeItemPolygon(); 10 | private: 11 | void calculateShape() override; 12 | void sizeChanged(); 13 | void shapeInit() override; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemRect1.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeItemRect1.h" 2 | 3 | ShapeItemRect1::ShapeItemRect1(ShapeMode shape_mode) : 4 | ShapeItemBase(EShapeType::sRectangle1Add) 5 | { 6 | m_shape_mode = shape_mode; 7 | shapeInit(); 8 | 9 | } 10 | 11 | ShapeItemRect1::~ShapeItemRect1() 12 | { 13 | } 14 | 15 | void ShapeItemRect1::calculateShape() 16 | { 17 | if (this->sender() == nullptr) 18 | { 19 | sizeChanged(); 20 | } 21 | else 22 | { 23 | activeHandle = dynamic_cast(this->sender()); 24 | 25 | if (activeHandle->getType() == cCenter) 26 | { 27 | //this->moveBy(activeHandle->getDx(), activeHandle->getDy()); 28 | } 29 | else if (activeHandle->getType() == cRotate) 30 | { 31 | 32 | } 33 | else { 34 | 35 | sizeChanged(); 36 | } 37 | } 38 | } 39 | 40 | void ShapeItemRect1::shapeInit() 41 | { 42 | ControlList.append(new ShapeControlItem(this, ControlItemType::cCenter, QPointF(50, 50))); 43 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 10))); 44 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 10))); 45 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 90))); 46 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 90))); 47 | itemPolygon.append(QPointF(ControlList[1]->x(), ControlList[1]->y())); 48 | itemPolygon.append(QPointF(ControlList[2]->x(), ControlList[2]->y())); 49 | itemPolygon.append(QPointF(ControlList[3]->x(), ControlList[3]->y())); 50 | itemPolygon.append(QPointF(ControlList[4]->x(), ControlList[4]->y())); 51 | ControlList[2]->setVisible(false); 52 | ControlList[4]->setVisible(false); 53 | for (auto elem : ControlList) 54 | { 55 | connect(elem, SIGNAL(PositionChanged()), this, SLOT(calculateShape())); 56 | } 57 | calculateShape(); 58 | } 59 | 60 | void ShapeItemRect1::sizeChanged() 61 | { 62 | activeHandle = dynamic_cast(this->sender()); 63 | 64 | ControlList[0]->setX(0.5 * (ControlList[1]->x() + ControlList[3]->x())); 65 | ControlList[0]->setY(0.5 * (ControlList[1]->y() + ControlList[3]->y())); 66 | 67 | ControlList[2]->setX(ControlList[3]->x()); 68 | ControlList[2]->setY(ControlList[1]->y()); 69 | 70 | ControlList[4]->setX(ControlList[1]->x()); 71 | ControlList[4]->setY(ControlList[3]->y()); 72 | 73 | itemPolygon[0] = ControlList[1]->getCenterPointF(); 74 | itemPolygon[1] = ControlList[2]->getCenterPointF(); 75 | itemPolygon[2] = ControlList[3]->getCenterPointF(); 76 | itemPolygon[3] = ControlList[4]->getCenterPointF(); 77 | 78 | ItemPath.clear(); 79 | ItemPath.addPolygon(itemPolygon); 80 | ItemPath.closeSubpath(); 81 | ItemShape.clear(); 82 | ItemShape.addRect(ItemPath.boundingRect()); 83 | } 84 | 85 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemRect1.h: -------------------------------------------------------------------------------- 1 | #include "ShapeItemBase.h" 2 | 3 | class ShapeItemRect1 4 | :public ShapeItemBase 5 | { 6 | public: 7 | ShapeItemRect1(ShapeMode shape_mode); 8 | 9 | ~ShapeItemRect1(); 10 | private: 11 | void calculateShape() override; 12 | 13 | void shapeInit() override; 14 | 15 | void sizeChanged(); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemRect2.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeItemRect2.h" 2 | 3 | ShapeItemRect2::ShapeItemRect2(ShapeMode shape_mode, QPointF pos) : 4 | ShapeItemBase(EShapeType::sRectangle2Add) 5 | { 6 | m_shape_mode = shape_mode; 7 | shapeInit(); 8 | } 9 | 10 | ShapeItemRect2::~ShapeItemRect2() 11 | { 12 | } 13 | 14 | void ShapeItemRect2::calculateShape() 15 | { 16 | if (this->sender() == nullptr) 17 | { 18 | sizeChanged(); 19 | } 20 | else 21 | { 22 | activeHandle = dynamic_cast(this->sender()); 23 | 24 | if (activeHandle->getType() == cCenter) 25 | { 26 | //this->moveBy(activeHandle->getDx(), activeHandle->getDy()); 27 | } 28 | else if (activeHandle->getType() == cRotate) 29 | { 30 | rotateShape(activeHandle->getDy()); 31 | } 32 | else { 33 | 34 | sizeChanged(); 35 | } 36 | } 37 | } 38 | 39 | void ShapeItemRect2::rotateShape(qreal delta) 40 | { 41 | m_transform = this->transform(); 42 | m_transform.rotate(1); 43 | qreal delta_angle = 1.0; 44 | if (delta > 0) 45 | { 46 | delta_angle = 1.0; 47 | } 48 | else 49 | { 50 | delta_angle = -1.0; 51 | } 52 | m_transform = m_transform.rotate(delta_angle); 53 | this->setTransform(m_transform); 54 | } 55 | 56 | void ShapeItemRect2::shapeInit() 57 | { 58 | ControlList.append(new ShapeControlItem(this, ControlItemType::cCenter, QPointF(50, 50))); 59 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 10))); 60 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 10))); 61 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 90))); 62 | ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 90))); 63 | ControlList.append(new ShapeControlItem(this, ControlItemType::cRotate, QPointF(50, 10))); 64 | itemPolygon.append(QPointF(ControlList[1]->x(), ControlList[1]->y())); 65 | itemPolygon.append(QPointF(ControlList[2]->x(), ControlList[2]->y())); 66 | itemPolygon.append(QPointF(ControlList[3]->x(), ControlList[3]->y())); 67 | itemPolygon.append(QPointF(ControlList[4]->x(), ControlList[4]->y())); 68 | ControlList[2]->setVisible(false); 69 | ControlList[4]->setVisible(false); 70 | for (auto elem : ControlList) 71 | { 72 | connect(elem, SIGNAL(PositionChanged()), this, SLOT(calculateShape())); 73 | } 74 | calculateShape(); 75 | } 76 | 77 | void ShapeItemRect2::sizeChanged() 78 | { 79 | activeHandle = dynamic_cast(this->sender()); 80 | 81 | ControlList[0]->setX(0.5 * (ControlList[1]->x() + ControlList[3]->x())); 82 | ControlList[0]->setY(0.5 * (ControlList[1]->y() + ControlList[3]->y())); 83 | ControlList[5]->setX(ControlList[0]->x()); 84 | ControlList[5]->setY(ControlList[1]->y()); 85 | 86 | ControlList[2]->setX(ControlList[3]->x()); 87 | ControlList[2]->setY(ControlList[1]->y()); 88 | 89 | ControlList[4]->setX(ControlList[1]->x()); 90 | ControlList[4]->setY(ControlList[3]->y()); 91 | 92 | itemPolygon[0] = ControlList[1]->getCenterPointF(); 93 | itemPolygon[1] = ControlList[2]->getCenterPointF(); 94 | itemPolygon[2] = ControlList[3]->getCenterPointF(); 95 | itemPolygon[3] = ControlList[4]->getCenterPointF(); 96 | 97 | ItemPath.clear(); 98 | ItemPath.addPolygon(itemPolygon); 99 | ItemPath.closeSubpath(); 100 | ItemShape.clear(); 101 | ItemShape.addRect(ItemPath.boundingRect()); 102 | } 103 | 104 | -------------------------------------------------------------------------------- /ShapeDrawer/ShapeItemRect2.h: -------------------------------------------------------------------------------- 1 | #include "ShapeItemBase.h" 2 | 3 | class ShapeItemRect2 4 | :public ShapeItemBase 5 | { 6 | public: 7 | ShapeItemRect2(ShapeMode shape_mode, QPointF pos = QPointF(0, 0)); 8 | 9 | ~ShapeItemRect2(); 10 | private: 11 | QTransform m_transform; 12 | private: 13 | void calculateShape() override; 14 | 15 | void rotateShape(qreal delta) override; 16 | 17 | void shapeInit() override; 18 | 19 | void sizeChanged(); 20 | }; 21 | 22 | --------------------------------------------------------------------------------