#pragma once #include "transform3d.h" #include "Geometry.h" #include "StructureGraph.h" #include "GraphCorresponder.h" static QString TRANS = "TRANS"; static QString REF = "REF"; static QString PARALLEL = "PARALLEL"; static QString ORTHOGONAL = "ORTHOGONAL"; static QString COPLANAR = "COPLANAR"; static QString CONNECTED = "CONNECTED"; // for all connected pairs static QString NONE = "NONE"; class PairRelation { public: PairRelation():n1(0),n2(0),tag(true),type(NONE){} PairRelation(Structure::Node* node1, Structure::Node* node2):n1(node1),n2(node2){} bool isDegenerated(){return n1==0 || n2==0;} Structure::Node* n1; Structure::Node* n2; QString type; //for connected pair, deviation is: mini distance between the skeleton' s control points of n1 & n2. has been normalized by graph->bbox().diagonal().norm() //for translation pair, deviation is: mean distance between the skeleton' s control points of n1 & that of n2 after translation. has been normalized by n1 & n2's diameters double deviation; bool tag; double diameter; // diameter of the pair Eigen::Vector3d trans_vec;// for TRANS //Eigen::Vector3d normal; // for coplanar //Eigen::Vector3d point; // for coplanar friend QTextStream& operator<<(QTextStream& os, const PairRelation& pr); }; static QString TRANS_SYMMETRY = "TRANS_SYMMETRY"; // build from Trans pair, except AXIS_SYMMETRY static QString AXIS_SYMMETRY = "AXIS_SYMMETRY"; static QString REF_SYMMETRY = "REF_SYMMETRY"; struct GroupRelation { GroupRelation():deviation(0.0){} QVector ids; //QSet ids; QString type; QString note;// from trans or ref pair double diameter; // group diameter double deviation; // absolute mean deviation bool tag; Point_3 center; // for AXIS_SYMMETRY Vector_3 direction; // normalized. line direction for AXIS_SYMMETRY Eigen::Vector3d normal;// normalized. for coplanar & REF_SYMMETRY group Eigen::Vector3d point;// for coplanar group & REF_SYMMETRY group bool equal(GroupRelation& gr); friend QTextStream& operator<<(QTextStream& os, const GroupRelation& gr); }; bool isTaged(const PairRelation &pr); bool isTagedGr(const GroupRelation &gr); void saveToFile(QString filename, QVector& prs); void saveToFile(QString filename, QVector& grs); template int countByType(QVector& prs, QString& type) { int i(0); foreach(T pr, prs) { if ( 0 == type.compare(pr.type)) ++i; } return i; } class RelationDetector { public: RelationDetector(Structure::Graph* g, const QString& logprefix, int ith, double normalizeCoef, int pointLevel=1, int logLevel=0); ~RelationDetector(){logFile_.close();} ////////////////////////////////////////////////// // find nodes in the source or target shape // bSource == true means that the id is from target shape, & we want to find its corresponded node in source shape, then graph should be source std::vector findNodesInST(QString id, Structure::Graph *graph, QVector &corres, bool bSource); // find nodes in a blended shape, all returned nodes are not degenerated. // bSource == true means that the id is from source shape std::vector findNodesInB(QString id, Structure::Graph *graph, QVector &corres, bool bSource); ///////////////////////////////////////////////// Eigen::MatrixXd node2matrix(Structure::Node* node, int pointLevel); int extractCpts( Structure::Node * n, std::vector& mcpts, int pointsLevel); void vectorPts2MatrixPts(const std::vector& ptsin, Eigen::MatrixXd& ptsout); std::vector matrixPts2VectorPts(Eigen::MatrixXd& ptsin); //////////////////////////////////////////////// static Segment_3 curve2segment(Structure::Node * n); static Line_3 curve2line(Structure::Node * n); static Eigen::Vector3d curve2vectorNormalized(Structure::Node * n); static std::vector sheet2rect(Structure::Node * n); static void sheet2plane(Structure::Sheet * s, Vector3& point, Vector3& normal); // normalized static bool node2direction(Structure::Node * n, Vector_3& result); // output: // point // normal // only work for two curve node void createPlane(Structure::Node *n1,Structure::Node *n2, Eigen::Vector3d& point, Eigen::Vector3d& normal); ////////////////////////////////////////////////// double computePairDiameter(PairRelation& pr); // relative to the diameter of the graph, i.e. model double computeGroupDiameter(GroupRelation& gr); void computeGroupCenter(GroupRelation& gr); void findRefPlane(Structure::Node* n1, Structure::Node* n2, Eigen::Vector3d& center,Eigen::Vector3d& normal); double fixDeviationByPartName(const QString& s1, const QString& s2, double deviation, double times=0.5); // we do not order part in a group by ref plane // return mean deviation of the group // precondition: none double computeRefSymmetryGroupDeviation(GroupRelation& gr, int pointLevel); // order part in a group by angle around the axis // return mean deviation of the group // precondition: center & direction of gr is known. double computeAxisSymmetryGroupDeviationSortParts(GroupRelation& gr, int pointLevel); // return mean deviation of the group // precondition 1: center & direction of gr is known. // precondition 2: order of parts is determined double computeAxisSymmetryGroupDeviation(const GroupRelation& gr, int pointLevel); // compute the center and direction of the group void computeTransGroupInfo(GroupRelation &gr, QSet& ids); static Structure::Link* findLink(Structure::Node *n1, Structure::Node *n2, Structure::Graph * graph); static double computeDeviationByLink(Structure::Link* link); protected: Eigen::Vector3d computeCptsCenter(Structure::Node* nn); double errorOfRefSymmGroup(std::vector &nodes, Eigen::Vector3d& center, Eigen::Vector3d& normal, int pointLevel); public: double thRadiusRadio_; double thTransRadio_; double thRefRadio_; double thParal_; double thOthog_; double thCopla_; double thRefGroup_; double thAxisGroup_; double thAxisDeviationRadio_; double thCoplaGroup_; Structure::Graph* graph_; double normalizeCoef_; int pointLevel_;// 0 for main control points, 1 for all control points, 2 for all points. protected: QFile logFile_; QTextStream logStream_; int logLevel_; // 0 for no log; 1 for coarse log; 2 for detailed log };