return Standard_True;
}
- gp_Pnt aMinMaxPnts[2] = { gp_Pnt (theMinPnt.x(), theMinPnt.y(), theMinPnt.z()),
- gp_Pnt (theMaxPnt.x(), theMaxPnt.y(), theMaxPnt.z())};
-
- gp_Pnt anOffset[3] = { gp_Pnt (aMinMaxPnts[1].X() - aMinMaxPnts[0].X(), 0.0, 0.0),
- gp_Pnt (0.0, aMinMaxPnts[1].Y() - aMinMaxPnts[0].Y(), 0.0),
- gp_Pnt (0.0, 0.0, aMinMaxPnts[1].Z() - aMinMaxPnts[0].Z()) };
-
- Standard_Integer aSign = 1;
- for (Standard_Integer aPntsIdx = 0; aPntsIdx < 2; aPntsIdx++)
- {
- for (Standard_Integer aCoordIdx = 0; aCoordIdx < 3; aCoordIdx++)
- {
- gp_Pnt anOffsetPnt = aMinMaxPnts [aPntsIdx].XYZ() + aSign * anOffset [aCoordIdx].XYZ();
- if (isIntersectBoundary (aMinMaxPnts [aPntsIdx], anOffsetPnt)
- || isIntersectBoundary (anOffsetPnt, anOffsetPnt.XYZ() + aSign * anOffset [(aCoordIdx + 1) % 3].XYZ()))
- {
+ // Disable full-inside optimization for AABB nodes in polyline mode to avoid false inclusions.
+ // Force per-element checks downstream (elementIsInside).
*theInside &= Standard_False;
- return Standard_True;
- }
- }
- aSign = -aSign;
- }
return Standard_True;
}
return Standard_False;
}
+// =======================================================================
+// function : OverlapsPoint
+// purpose :
+// =======================================================================
+Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsPoint (const gp_Pnt& thePnt) const
+{
+ return IsInsideByProjection (thePnt);
+}
+
// =======================================================================
// function : OverlapsPolygon
// purpose :
OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, aFrustum.get())
}
}
+
+// =======================================================================
+// function : IsInsideByProjection
+// purpose : Robust 2D inclusion test using original polyline (fills gaps)
+// =======================================================================
+Standard_Boolean SelectMgr_TriangularFrustumSet::IsInsideByProjection (const gp_Pnt& thePnt) const
+{
+ if (myBoundaryPoints.Size() < 6) // at least 3 near + 3 far
+ {
+ return Standard_False;
+ }
+
+ // Build plane by first frustum triangle (near plane)
+ const gp_Pnt& p0 = myFrustums.First()->myVertices[0];
+ const gp_Pnt& p1 = myFrustums.First()->myVertices[1];
+ const gp_Pnt& p2 = myFrustums.First()->myVertices[2];
+ gp_Pln aPln (p0, gp_Vec(p0,p1).Crossed (gp_Vec(p0,p2)));
+
+ // Project point onto plane along plane normal
+ gp_Pnt aProj = thePnt;
+ Standard_Real aA, aB, aC, aD; aPln.Coefficients (aA, aB, aC, aD);
+ const Standard_Real n2 = aA*aA + aB*aB + aC*aC;
+ if (n2 > gp::Resolution())
+ {
+ const Standard_Real s = (aA * aProj.X() + aB * aProj.Y() + aC * aProj.Z() + aD) / n2;
+ aProj.SetCoord (aProj.X() - aA * s,
+ aProj.Y() - aB * s,
+ aProj.Z() - aC * s);
+ }
+
+ // Project near boundary loop and perform winding test in 2D
+ const Standard_Integer aFacesNb = myBoundaryPoints.Size() / 2;
+ const Standard_Integer aLowerIdx = myBoundaryPoints.Lower();
+
+ // Choose 2D axes by dominant plane normal component
+ int drop = 0; if (Abs(aB) > Abs(aA) && Abs(aB) >= Abs(aC)) drop = 1; else if (Abs(aC) > Abs(aA) && Abs(aC) > Abs(aB)) drop = 2;
+ auto proj2d = [drop](const gp_Pnt& P) {
+ if (drop == 0) return gp_XY (P.Y(), P.Z());
+ if (drop == 1) return gp_XY (P.X(), P.Z());
+ return gp_XY (P.X(), P.Y());
+ };
+
+ gp_XY P = proj2d (aProj);
+ Standard_Boolean inside = Standard_False;
+ for (Standard_Integer i = 0, j = aFacesNb - 1; i < aFacesNb; j = i++)
+ {
+ const gp_Pnt& Pi3d = myBoundaryPoints.Value (aLowerIdx + i);
+ const gp_Pnt& Pj3d = myBoundaryPoints.Value (aLowerIdx + j);
+ const gp_XY Ai = proj2d (Pi3d);
+ const gp_XY Aj = proj2d (Pj3d);
+ const Standard_Boolean intersect = ((Ai.Y() > P.Y()) != (Aj.Y() > P.Y()))
+ && (P.X() < (Aj.X()-Ai.X()) * (P.Y()-Ai.Y()) / (Aj.Y()-Ai.Y() + 1e-300) + Ai.X());
+ if (intersect) inside = !inside;
+ }
+ return inside;
+}
const SelectMgr_ViewClipRange& theClipRange,
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
- //! Always returns FALSE (not applicable to this selector).
- virtual Standard_Boolean OverlapsPoint (const gp_Pnt& ) const Standard_OVERRIDE
- {
- return Standard_False;
- }
+ Standard_EXPORT virtual Standard_Boolean OverlapsPoint (const gp_Pnt& thePnt) const Standard_OVERRIDE;
Standard_EXPORT virtual Standard_Boolean OverlapsPolygon (const TColgp_Array1OfPnt& theArrayOfPnts,
Select3D_TypeOfSensitivity theSensType,
//! Dumps the content of me into the stream
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
+public:
+ //! 2D inclusion test: project 3D point onto selection plane and check inside original polyline
+ Standard_EXPORT Standard_Boolean IsInsideByProjection (const gp_Pnt& thePnt) const;
+
private:
//! Checks whether the segment intersects with the boundary of the current volume selection