11 #include <QApplication>
12 #include <QProgressDialog>
43 unsigned subFamilyIndex,
44 unsigned subFamilyCount,
50 double S = dip / 90.0;
53 if (subFamilyCount > 1) {
54 assert(subFamilyIndex >= 1);
69 double angularStep_deg,
78 iDip =
static_cast<unsigned>(
floor(dip / angularStep_deg));
79 if (iDip == dSteps) iDip--;
80 iDipDir =
static_cast<unsigned>(
floor(dipDir / angularStep_deg));
81 if (iDipDir == ddSteps) iDipDir--;
86 double angularStep_deg) {
89 return QString(
"%1_%2").arg(dipDir).arg(dip);
93 return QString(
"f%1").arg(subFamilyIndex, 4, 10, QChar(
'0'));
102 double angularStep_deg,
104 size_t count = family.size();
105 if (
count == 0)
return true;
107 double dip = (iDip + 0.5) * angularStep_deg;
108 double dipDir = (iDipDir + 0.5) * angularStep_deg;
110 QString familyName =
GetFamilyName(dip, dipDir, angularStep_deg);
114 QString(
"F%1_").arg(familyIndex, 2, 10, QChar(
'0')) +
116 if (parent) parent->
addChild(familyGroup);
119 for (FacetSet::iterator it = family.begin(); it != family.end(); ++it) {
121 QVariant(
static_cast<uint>(familyIndex)));
126 unsigned subFamilyIndex = 0;
130 family[0]->setMetaData(
132 QVariant(
static_cast<uint>(++subFamilyIndex)));
135 familyGroup->
addChild(subFamilyGroup);
136 assert(family[0]->getParent() == 0);
137 subFamilyGroup->
addChild(family[0]);
142 if (
dist <= maxDist) {
144 family[1]->setMetaData(
146 QVariant(
static_cast<uint>(subFamilyIndex)));
147 assert(family[1]->getParent() == 0);
148 subFamilyGroup->
addChild(family[1]);
151 family[1]->setMetaData(
153 QVariant(
static_cast<uint>(++subFamilyIndex)));
156 familyGroup->
addChild(subFamilyGroup2);
157 assert(family[1]->getParent() == 0);
158 subFamilyGroup2->
addChild(family[1]);
165 for (
unsigned it1 = 0; it1 + 1 !=
count; ++it1) {
166 for (
unsigned it2 = it1 + 1; it2 !=
count; ++it2) {
168 family.at(it1), family.at(it2));
177 std::pair<unsigned, unsigned> bestCouple(0, 0);
179 for (
unsigned i = 0; i + 1 <
count; ++i) {
183 for (
unsigned j = i + 1; j <
count; ++j) {
187 if (bestCoupleDist < 0 ||
190 bestCouple.first = i;
191 bestCouple.second = j;
192 bestCoupleDist = distMat.
getValue(i, j);
199 if (bestCoupleDist < 0 || bestCoupleDist > maxDist)
203 std::vector<unsigned> subFamily(2);
204 subFamily[0] = bestCouple.first;
205 subFamily[1] = bestCouple.second;
207 distMat.
setValue(bestCouple.first, bestCouple.first, -1);
208 distMat.
setValue(bestCouple.second, bestCouple.second, -1);
213 unsigned bestIndex = 0;
214 for (
unsigned i = 0; i <
count; ++i) {
219 for (
unsigned j = 0; j < subFamily.size();
223 if (
dist < maxDist) {
225 if (minDist < 0 ||
dist < minDist)
234 (bestDist < 0 || minDist < bestDist)) {
243 subFamily.push_back(bestIndex);
245 distMat.
setValue(bestIndex, bestIndex, -1);
257 familyGroup->
addChild(subFamilyGroup);
258 for (
unsigned j = 0; j < subFamily.size(); ++j) {
259 ccFacet* facet = family.at(subFamily[j]);
261 QVariant(
static_cast<uint>(
273 for (
unsigned i = 0; i <
count; ++i) {
280 QVariant(
static_cast<uint>(
284 familyGroup->
addChild(subFamilyGroup);
292 for (
unsigned i = 0; i <
count; ++i)
299 unsigned subFamilyCount = subFamilyIndex;
300 if (subFamilyCount) {
301 assert(subFamilyCount > 0);
303 for (
unsigned i = 0; i <
count; ++i) {
307 subFamilyCount, &darkCol);
321 double angularStep_deg,
323 assert(facetGroup && angularStep_deg > 0 && maxDist >= 0);
329 size_t facetCount = facets.size();
330 if (facetCount == 0) {
337 for (
size_t i = 0; i < facetCount; ++i) {
348 unsigned dSteps =
static_cast<unsigned>(
ceil(90.0 / angularStep_deg));
350 unsigned ddSteps =
static_cast<unsigned>(
ceil(360.0 / angularStep_deg));
353 if (facetCount == 1) {
359 unsigned iDip = 0, iDipDir = 0;
364 angularStep_deg, maxDist);
366 unsigned gridSize = dSteps * ddSteps;
374 memset(grid, 0,
sizeof(
FacetSet*) * gridSize);
376 QProgressDialog pDlg(
"Families classification", QString(), 0,
377 static_cast<int>(facetCount));
379 QApplication::processEvents();
382 unsigned setCount = 0;
383 for (
size_t i = 0; i < facetCount; ++i) {
386 unsigned iDip = 0, iDipDir = 0;
390 unsigned facetIndex = iDipDir + iDip * ddSteps;
391 assert(facetIndex < gridSize);
400 grid[iDipDir + iDip * ddSteps] = set;
405 set->push_back(facet);
406 }
catch (
const std::bad_alloc&) {
412 pDlg.setValue(
static_cast<int>(i));
416 unsigned familyIndex = 0;
418 QProgressDialog pDlg(
"Sub-families classification",
420 static_cast<int>(setCount));
422 QApplication::processEvents();
427 for (
unsigned j = 0; j < dSteps; ++j) {
428 for (
unsigned i = 0; i < ddSteps; ++i, ++set) {
432 facetGroup, **set, ++familyIndex, j, i,
433 angularStep_deg, maxDist);
441 pDlg.setValue(++progress);
450 for (
unsigned i = 0; i < gridSize; ++i)
451 if (grid[i])
delete grid[i];
459 for (
size_t i = 0; i < facetCount; ++i) {
float PointCoordinateType
Type of the coordinates of a (N-D) point.
static void GetFamilyIndexes(ccFacet *facet, unsigned dSteps, unsigned ddSteps, double angularStep_deg, unsigned &iDip, unsigned &iDipDir)
static QString GetFamilyName(double dip, double dipDir, double angularStep_deg)
static QString GetSubFamilyName(int subFamilyIndex)
static void GenerateSubfamilyColor(ecvColor::Rgb &col, double dip, double dipDir, unsigned subFamilyIndex, unsigned subFamilyCount, ecvColor::Rgb *darkCol=0)
Generates a given sub-family color.
std::vector< ccFacet * > FacetSet
Set of facets (pointers to)
static bool ProcessFamiliy(ccHObject *parent, FacetSet &family, unsigned familyIndex, unsigned iDip, unsigned iDipDir, double angularStep_deg, double maxDist)
Subdivides a set of facets with similar orientation.
static PointCoordinateType CommputeHDistBetweenFacets(const ccFacet *f1, const ccFacet *f2)
Computes minimal 'orthogonal' distance between two facets.
static bool ByOrientation(ccHObject *facetGroup, double angularStep_deg, double maxDist)
Classifies the facets based on their orientation.
Type dot(const Vector3Tpl &v) const
Dot product.
ccPolyline * getContour()
Returns contour polyline (if any)
CCVector3 getNormal() const override
Returns the entity normal.
void setColor(const ecvColor::Rgb &rgb)
Sets the facet unique color.
const CCVector3 & getCenter() const
Returns the facet center.
Hierarchical CLOUDVIEWER Object.
void removeAllChildren()
Removes all children.
void removeDependencyWith(ccHObject *otherObject)
Removes any dependency flags with a given object.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
ccHObject * getParent() const
Returns parent object.
void removeChild(ccHObject *child)
unsigned filterChildren(Container &filteredChildren, bool recursive=false, CV_CLASS_ENUM filter=CV_TYPES::OBJECT, bool strict=false) const
Collects the children corresponding to a certain pattern.
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
static void ConvertNormalToDipAndDipDir(const CCVector3 &N, PointCoordinateType &dip_deg, PointCoordinateType &dipDir_deg)
Converts a normal vector to geological 'dip direction & dip' parameters.
void setMetaData(const QString &key, const QVariant &data)
Sets a meta-data element.
QVariant getMetaData(const QString &key) const
Returns a given associated meta data.
void setColor(const ecvColor::Rgb &col)
Sets the polyline color.
void setWidth(PointCoordinateType width)
Sets the width of the line.
bool isValid() const
Returns matrix validity.
void setValue(unsigned row, unsigned column, Scalar value)
Sets a particular matrix value.
Scalar getValue(unsigned row, unsigned column) const
Returns a particular matrix value.
static Rgb hsl2rgb(float H, float S, float L)
Converts a HSL color to RGB color space.
__host__ __device__ float2 fabs(float2 v)
static const QString s_OriSubFamilyKey
static const QString s_OriFamilyKey
static const QString s_OriFamilyNameKey
const double c_darkColorRatio
static double dist(double x1, double y1, double x2, double y2)
static void error(char *msg)
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)