Skip to content

Conversation

@dpasukhi
Copy link
Owner

No description provided.

- Added `D0Local`, `D1Local`, `D2Local`, `D3Local` methods to `BSplCLib_Cache` and `BSplSLib_Cache` classes
- Added accessor methods to `Geom_BSplineCurve` and `Geom_BSplineSurface` for direct handle access to internal arrays
- Comprehensive test coverage for both curve and surface cache implementations
…d Introduce OffsetUtils

- Removed GeomEvaluator classes for curves and surfaces, streamlining the evaluation process.
- Introduced Geom2d_OffsetUtils and Geom_OffsetUtils for handling offset calculations.
- Updated GeomAdaptor classes to utilize new utility functions for offset evaluations.
- Enhanced package structure by removing obsolete files and optimizing includes.
- Improved performance and maintainability by reducing dependencies on removed evaluator classes.
- Introduced Geom_ExtrusionUtils.pxx and Geom_RevolutionUtils.pxx to provide shared utility functions for evaluating points and derivatives on linear extrusion and revolution surfaces.
- Updated Geom_SurfaceOfLinearExtrusion and Geom_SurfaceOfRevolution classes to utilize the new utility functions for D0, D1, D2, D3, and DN evaluations, improving code clarity and maintainability.
- Enhanced GeomAdaptor_Surface to integrate the new utility functions for extrusion and revolution surface evaluations, streamlining the overall surface handling process.
… to 2025; refactor DN function to store original point for efficiency
…tructures

- Merged various surface evaluation data structures into the GeomAdaptor_Surface class, including ExtrusionData, RevolutionData, OffsetData, BezierData, and BSplineData.
- Updated method signatures and internal references to utilize the new structures, enhancing code clarity and maintainability.
- Removed obsolete structures and streamlined the handling of surface-specific evaluation data, improving overall performance and organization.
- Replaced instances of Geom2dAdaptor_OffsetCurveData with Geom2dAdaptor_Curve::OffsetData across the Geom2dAdaptor_Curve and BRepAdaptor_Curve2d classes.
- Updated method implementations to utilize the new OffsetData structure, enhancing code clarity and maintainability.
- Streamlined the handling of curve-specific evaluation data, improving overall organization and performance.
- Unified the handling of curve-specific evaluation data by introducing BezierData and BSplineData structures.
- Updated ShallowCopy methods in both Geom2dAdaptor_Curve and BRepAdaptor_Curve2d to accommodate the new data structures, improving code clarity and maintainability.
- Streamlined the evaluation process for Bezier and B-spline curves, enhancing performance and organization of the codebase.
…tions

- Introduced Geom_OffsetCurveUtils and Geom_OffsetSurfaceUtils to provide dedicated utility functions for offset calculations in curves and surfaces.
- Updated Geom_OffsetCurve and Geom_OffsetSurface classes to utilize the new utility functions, improving code clarity and maintainability.
- Replaced instances of Geom_OffsetUtils with the new utility functions across relevant classes, streamlining the evaluation process for offset points and derivatives.
- Enhanced GeomAdaptor classes to integrate the new utilities, optimizing the overall handling of offset evaluations.
…Clarity

- Replaced instances of gp_Dir with gp_XYZ in Geom_ExtrusionUtils and related classes to ensure consistent handling of extrusion direction as normalized XYZ vectors.
- Updated method signatures and internal references in Geom_SurfaceOfLinearExtrusion and Geom_SurfaceOfRevolution to utilize the new gp_XYZ type, enhancing clarity and maintainability.
- Removed unnecessary includes and streamlined the codebase for improved organization and performance.
- Introduced AdjustDerivative function in Geom_OffsetCurveUtils to handle derivative adjustments at singular points using Taylor series approximation.
- Implemented ShiftPoint function in Geom_OffsetSurfaceUtils to iteratively shift evaluation points towards the center of the parametric space when normal calculations fail.
- Updated EvaluateD0, EvaluateD1, EvaluateD2, and EvaluateD3 functions in Geom_OffsetSurfaceUtils to incorporate retry mechanisms for singular points, improving robustness in offset evaluations.
- Enhanced GeomAdaptor_Curve and GeomAdaptor_Surface classes to utilize the new utility functions, optimizing the handling of offset evaluations and ensuring better performance in singular scenarios.
…ndle zero derivatives

- Added ReplaceDerivative function to replace a zero derivative by stepping away and recomputing, addressing the CSLib_InfinityOfSolutions case.
- Updated ComputeSingularNormal and EvaluateD0 functions to utilize ReplaceDerivative for improved handling of singular cases and robustness in normal calculations.
- Enhanced derivative computation logic to ensure accurate evaluations in scenarios where derivatives may be zero.
- Removed deprecated calculateD0, calculateD1, calculateD2, and calculateD3 methods from Geom_OffsetSurface, streamlining the class interface.
- Enhanced EvaluateD0, EvaluateD1, EvaluateD2, and EvaluateD3 functions in Geom_OffsetSurfaceUtils to utilize a more robust mechanism for handling singular points and derivatives.
- Introduced a new EvaluateDN function to compute arbitrary order derivatives of the offset surface, improving the handling of singular cases.
- Updated GeomAdaptor_Surface to include a Bounds method for better parameter management, enhancing the overall usability of the surface class.
- Improved code clarity and maintainability by consolidating derivative evaluation logic and removing redundant code.
- Reformatted function calls in offsetD0, offsetD1, offsetD2, offsetD3, and offsetDN methods for better readability by aligning parameters vertically.
- Enhanced error handling in offsetDN to ensure proper exception throwing when evaluation fails, improving robustness in derivative calculations.
- Streamlined the code structure to enhance clarity and maintainability, aligning with recent updates in Geom_OffsetSurfaceUtils.
- Replaced existing derivative calculation methods in Geom_OffsetCurve with new EvaluateD0, EvaluateD1, EvaluateD2, and EvaluateD3 functions for improved clarity and maintainability.
- Removed the adjustDerivative method to streamline the class interface, leveraging the new utility functions for handling singular points and derivatives.
- Updated GeomAdaptor_Curve to utilize the new evaluation functions, optimizing the handling of offset evaluations and ensuring better performance in singular scenarios.
- Updated D0, D1, D2, and D3 methods in Geom_OffsetCurve to include error handling for offset point calculations, throwing exceptions when evaluations fail.
- Modified Geom_OffsetCurveUtils to return boolean values for evaluation functions, indicating success or failure, and adjusted corresponding methods in GeomAdaptor_Curve to handle these changes.
- Improved robustness and clarity in derivative evaluations, ensuring proper exception management in case of calculation issues.
…et Evaluations

- Updated D0, D1, D2, and D3 methods in Geom2d_OffsetCurve to utilize new EvaluateD0, EvaluateD1, EvaluateD2, and EvaluateD3 functions, enhancing error handling and robustness in offset point calculations.
- Removed the adjustDerivative method to streamline the interface, leveraging utility functions for handling singular points and derivatives.
- Modified Geom2dAdaptor_Curve to incorporate the new evaluation functions, ensuring better performance and clarity in offset evaluations.
- Improved exception management by throwing Standard_NullValue when evaluations fail, enhancing overall reliability.
…vative Evaluations

- Updated the DN method in Geom2d_OffsetCurve to utilize the new EvaluateDN function, improving error handling and clarity in derivative calculations.
- Simplified the derivative evaluation logic by removing the switch-case structure and leveraging the utility function for better maintainability.
- Modified Geom2dAdaptor_Curve to integrate the EvaluateDN function, ensuring consistent handling of offset evaluations and enhancing overall robustness.
- Improved exception management by throwing specific errors when derivative calculations fail, aligning with recent updates in the offset utilities.
…ve Evaluation

- Updated the DN method in Geom_OffsetCurve to utilize the EvaluateDN function, enhancing error handling and clarity in derivative calculations.
- Simplified the logic for derivative evaluations by removing the switch-case structure and leveraging the utility function for better maintainability.
- Modified GeomAdaptor_Curve to integrate the EvaluateDN function, ensuring consistent handling of offset evaluations and improving robustness.
- Enhanced exception management by throwing specific errors when derivative calculations fail, aligning with recent updates in the offset utilities.
…larity

- Updated the D3 and D2 derivative calculation methods in Geom2d_OffsetUtils to enhance clarity and maintainability.
- Simplified the logic for computing derivatives by adjusting the mathematical expressions, ensuring more straightforward evaluations.
- Improved overall readability of the code while maintaining the functionality of offset evaluations.
@dpasukhi
Copy link
Owner Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Dec 14, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link

coderabbitai bot commented Dec 14, 2025

Walkthrough

This pull request refactors geometric evaluation across B-spline curves, surfaces, and offset geometry. Changes include adding local-parameter evaluation methods to B-spline caching classes, replacing evaluator-based implementations with template utility functions for offset curves and surfaces, and restructuring adaptor classes to use variant-based data storage. The evaluator packages are removed entirely and superseded by new utility modules for extrusion and revolution surfaces. New public accessors expose B-spline array handles, and comprehensive test coverage is added for B-spline cache functionality across 2D and 3D cases with rational and non-rational geometries.

Pre-merge checks

❌ Failed checks (2 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Geom evaluator' is vague and generic, using a non-descriptive term that does not convey meaningful information about the changeset's primary intent or scope. Revise the title to be more specific and descriptive. Examples: 'Refactor geometry evaluation to use utility-based approach' or 'Replace GeomEvaluator with inline offset and extrusion utilities' would better communicate the core changes.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess whether a description exists or relates to the changeset. Add a detailed pull request description explaining the rationale for replacing GeomEvaluator classes with utility-based implementations and the benefits of this refactoring.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 84.40% which is sufficient. The required threshold is 80.00%.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (8)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.cxx (1)

298-303: Missing null check after DownCast in VTrim.

Similar to Load(), the DownCast result should be validated. If BasisCurve()->Trim() returns a non-GeomAdaptor_Curve type, HC will be null.

 Handle(Adaptor3d_Surface) GeomAdaptor_SurfaceOfRevolution::VTrim(const Standard_Real First,
                                                                  const Standard_Real Last,
                                                                  const Standard_Real Tol) const
 {
   Handle(GeomAdaptor_Curve) HC =
     Handle(GeomAdaptor_Curve)::DownCast(BasisCurve()->Trim(First, Last, Tol));
+  if (HC.IsNull())
+  {
+    throw Standard_TypeMismatch("GeomAdaptor_SurfaceOfRevolution::VTrim - Trim returned incompatible type");
+  }
   Handle(GeomAdaptor_SurfaceOfRevolution) HR =
     new GeomAdaptor_SurfaceOfRevolution(GeomAdaptor_SurfaceOfRevolution(HC, myAxis));
   return HR;
 }
src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx (1)

117-238: Reset myOscSurf on SetBasisSurface to avoid stale osculating data.

If SetBasisSurface() is called after previously setting a BSpline/Bezier surface, and the new basis surface is not BSpline/Bezier, myOscSurf currently remains pointing to the previous surface and can corrupt singular evaluation.

 void Geom_OffsetSurface::SetBasisSurface(const Handle(Geom_Surface)& S,
                                          const Standard_Boolean      isNotCheckC0)
 {
+  // Always reset; will be re-created below for BSpline/Bezier surfaces.
+  myOscSurf.reset();
+
   Standard_Real aUf, aUl, aVf, aVl;
   S->Bounds(aUf, aUl, aVf, aVl);
@@
   if (aCheckingSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))
       || aCheckingSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)))
   {
@@
     myOscSurf                   = std::make_unique<Geom_OsculatingSurface>(aCheckingSurf, Tol);
   }
 }
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Curve.cxx (2)

609-795: Consider throwing NotImplemented for DN(N>3) unconditionally (not only on EvaluateDN failure).

Right now, if EvaluateDN() ever returns true for N > 3, you’d return a value despite the message stating it’s unsupported.

 gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U, const Standard_Integer N) const
 {
   switch (myTypeCurve)
   {
@@
     case GeomAbs_OffsetCurve: {
+      if (N > 3)
+      {
+        throw Standard_NotImplemented("GeomAdaptor_Curve::DN: Derivative order > 3 not supported");
+      }
       const auto& anOffsetData = std::get<GeomAdaptor_OffsetCurveData>(myCurveData);
       gp_Vec      aDN;
       if (!Geom_OffsetCurveUtils::EvaluateDN(U,
@@
       {
-        if (N > 3)
-        {
-          throw Standard_NotImplemented(
-            "GeomAdaptor_Curve::DN: Derivative order > 3 not supported");
-        }
         throw Standard_NullValue("GeomAdaptor_Curve::DN: Unable to calculate offset DN");
       }
       return aDN;
     }

609-795: Add missing #include <Standard_NullValue.hxx> header.

The code throws Standard_NullValue multiple times (lines 609-795), but the header is not explicitly included in the translation unit. Add #include <Standard_NullValue.hxx> to prevent compilation failures on toolchains with strict header dependency checking, consistent with other exception includes like Standard_NotImplemented.hxx and Standard_NoSuchObject.hxx already present in the file.

src/ModelingData/TKG2d/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx (1)

231-309: BUG: “same curve, different params” doesn’t update OffsetData::BasisAdaptor
In the myCurve == C branch you only nullify Bezier/BSpline caches (Line 299-307). If this adaptor is reused with a different [UFirst, ULast], the nested OffsetData.BasisAdaptor keeps the old range, which can break boundary handling/caching and even correctness depending on adaptor internals.

@@
   else
   {
     // Same curve but potentially different parameters - invalidate cache
     if (auto* aBSplineData = std::get_if<BSplineData>(&myCurveData))
     {
       aBSplineData->Cache.Nullify();
     }
     else if (auto* aBezierData = std::get_if<BezierData>(&myCurveData))
     {
       aBezierData->Cache.Nullify();
     }
+    else if (auto* anOffsetData = std::get_if<OffsetData>(&myCurveData))
+    {
+      // Keep nested adaptor in sync with new trim range
+      Handle(Geom2d_OffsetCurve) anOffsetCurve = Handle(Geom2d_OffsetCurve)::DownCast(myCurve);
+      anOffsetData->BasisAdaptor =
+        new Geom2dAdaptor_Curve(anOffsetCurve->BasisCurve(), UFirst, ULast);
+    }
   }
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx (3)

359-455: Load(): nested adaptors ignore trim ranges + won’t update if only bounds change
For revolution/extrusion you construct GeomAdaptor_Curve without [myVFirst,myVLast] / [myUFirst,myULast], and the whole mySurfaceData population only happens when mySurface != S. If the same surface instance is reloaded with new bounds, nested adaptors (including offset BasisAdaptor) keep stale ranges. This is risky for boundary logic and cache validity.

@@
     else if (TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution))
     {
@@
-      aRevData.BasisCurve = new GeomAdaptor_Curve(aRevSurf->BasisCurve());
+      aRevData.BasisCurve = new GeomAdaptor_Curve(aRevSurf->BasisCurve(), myVFirst, myVLast);
@@
     else if (TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
     {
@@
-      anExtData.BasisCurve = new GeomAdaptor_Curve(anExtSurf->BasisCurve());
+      anExtData.BasisCurve = new GeomAdaptor_Curve(anExtSurf->BasisCurve(), myUFirst, myULast);
@@
     else if (TheType == STANDARD_TYPE(Geom_OffsetSurface))
     {
@@
       anOffsetData.BasisAdaptor = new GeomAdaptor_Surface(anOffSurf->BasisSurface(),
                                                           myUFirst,
                                                           myULast,
                                                           myVFirst,
                                                           myVLast,
                                                           myTolU,
                                                           myTolV);

1007-1188: BUG: cache paths ignore clamped (u,v) and still use raw (U,V)
You compute clamped u/v (Line 1014-1034) but Bezier/BSpline cache evaluation uses (U,V) for IsCacheValid, RebuildCache, and D1/D2 calls. That defeats the boundary snapping logic and can produce inconsistent results near trim bounds.

@@
     case GeomAbs_BezierSurface: {
       auto& aCache = std::get<BezierData>(mySurfaceData).Cache;
-      if (aCache.IsNull() || !aCache->IsCacheValid(U, V))
-        RebuildCache(U, V);
-      aCache->D1(U, V, P, D1U, D1V);
+      if (aCache.IsNull() || !aCache->IsCacheValid(u, v))
+        RebuildCache(u, v);
+      aCache->D1(u, v, P, D1U, D1V);
       break;
     }
@@
     case GeomAbs_BSplineSurface: {
@@
       else
       {
-        if (aBSplData.Cache.IsNull() || !aBSplData.Cache->IsCacheValid(U, V))
-          RebuildCache(U, V);
-        aBSplData.Cache->D1(U, V, P, D1U, D1V);
+        if (aBSplData.Cache.IsNull() || !aBSplData.Cache->IsCacheValid(u, v))
+          RebuildCache(u, v);
+        aBSplData.Cache->D1(u, v, P, D1U, D1V);
       }
       break;
     }

(Apply the same (U,V)(u,v) fix in the D2 cache paths at Line 1125-1142.)


301-355: BezierData variant missing from ShallowCopy causes runtime failure—add explicit handling.

The variant declaration includes BezierData as a valid alternative (in addition to Extrusion, Revolution, Offset, and BSpline data), but ShallowCopy() omits an explicit branch to copy it. When mySurfaceType == GeomAbs_BezierSurface, subsequent calls to std::get<BezierData>(mySurfaceData) in methods like RebuildCache(), D0(), and D1() will throw std::bad_variant_access because the variant holds std::monostate instead of BezierData. Add an explicit else-if branch after the BSplineData handler:

  else if (auto* aBSplineData = std::get_if<GeomAdaptor_Surface::BSplineData>(&mySurfaceData))
  {
    GeomAdaptor_Surface::BSplineData aNewData;
    aNewData.Surface = aBSplineData->Surface;
    // Cache is not copied - will be rebuilt on demand
    aCopy->mySurfaceData = aNewData;
  }
+  else if (std::holds_alternative<GeomAdaptor_Surface::BezierData>(mySurfaceData))
+  {
+    aCopy->mySurfaceData = GeomAdaptor_Surface::BezierData{};
+  }
🧹 Nitpick comments (19)
src/FoundationClasses/TKMath/GTests/BSplSLib_Cache_Test.cxx (1)

879-888: Consider extending assertions for Y and Z components.

The D1_DifferentDegrees_* tests only compare X components for point, tangentU, and tangentV. For completeness, consider adding Y and Z comparisons as done in other tests, or add a comment explaining why X-only checks are sufficient for these specific test cases.

       // Compare
       EXPECT_NEAR(aCachePnt.X(), aDirectPnt.X(), THE_TOLERANCE)
         << "DifferentDeg D1 point X mismatch at u=" << u << ", v=" << v;
+      EXPECT_NEAR(aCachePnt.Y(), aDirectPnt.Y(), THE_TOLERANCE)
+        << "DifferentDeg D1 point Y mismatch at u=" << u << ", v=" << v;
+      EXPECT_NEAR(aCachePnt.Z(), aDirectPnt.Z(), THE_TOLERANCE)
+        << "DifferentDeg D1 point Z mismatch at u=" << u << ", v=" << v;
       EXPECT_NEAR(aCacheTanU.X(), aDirectTanU.X(), THE_TOLERANCE)
         << "DifferentDeg D1 tanU X mismatch at u=" << u << ", v=" << v;
+      EXPECT_NEAR(aCacheTanU.Y(), aDirectTanU.Y(), THE_TOLERANCE)
+        << "DifferentDeg D1 tanU Y mismatch at u=" << u << ", v=" << v;
+      EXPECT_NEAR(aCacheTanU.Z(), aDirectTanU.Z(), THE_TOLERANCE)
+        << "DifferentDeg D1 tanU Z mismatch at u=" << u << ", v=" << v;
       EXPECT_NEAR(aCacheTanV.X(), aDirectTanV.X(), THE_TOLERANCE)
         << "DifferentDeg D1 tanV X mismatch at u=" << u << ", v=" << v;
+      EXPECT_NEAR(aCacheTanV.Y(), aDirectTanV.Y(), THE_TOLERANCE)
+        << "DifferentDeg D1 tanV Y mismatch at u=" << u << ", v=" << v;
+      EXPECT_NEAR(aCacheTanV.Z(), aDirectTanV.Z(), THE_TOLERANCE)
+        << "DifferentDeg D1 tanV Z mismatch at u=" << u << ", v=" << v;

Also applies to: 970-977

src/FoundationClasses/TKMath/BSplSLib/BSplSLib_Cache.hxx (1)

112-112: Minor inconsistency in parameter types.

The new D*Local methods use double for parameters, while the existing D0/D1/D2 methods use const Standard_Real&. Consider aligning the types for API consistency, though this is a minor style concern.

Also applies to: 121-122, 137-138

src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetCurve.hxx (1)

296-298: Consider using Standard_Real for consistency with public API.

The private member offsetValue uses double while all public methods (lines 97, 115, 128, 223) use Standard_Real. Although Standard_Real is typedef'd to double in OCCT, maintaining consistent type usage across the class improves readability and follows OCCT conventions.

 private:
   Handle(Geom2d_Curve) basisCurve;
-  double               offsetValue;
+  Standard_Real        offsetValue;
   GeomAbs_Shape        myBasisCurveContinuity;
src/ModelingData/TKG3d/Geom/Geom_OffsetCurve.hxx (1)

294-297: Prefer Standard_Real over double for consistency.

The offsetValue member was changed from Standard_Real to double. While functionally equivalent (Standard_Real is typedef'd to double), OCCT convention consistently uses Standard_Real for numeric members. Consider reverting to maintain codebase consistency.

 private:
   Handle(Geom_Curve) basisCurve;
   gp_Dir             direction;
-  double             offsetValue;
+  Standard_Real      offsetValue;
   GeomAbs_Shape      myBasisCurveContinuity;
src/FoundationClasses/TKMath/GTests/BSplCLib_Cache_Test.cxx (2)

90-91: Consider integer-based loop to avoid floating-point accumulation.

The loop for (double u = 0.0; u <= 1.0; u += 0.1) may miss u = 1.0 exactly due to floating-point accumulation errors. This pattern appears in all tests.

-  for (double u = 0.0; u <= 1.0; u += 0.1)
+  for (int i = 0; i <= 10; ++i)
   {
+    double u = i * 0.1;
     gp_Pnt aCachePnt, aDirectPnt;

444-447: Consider adding D3_RationalCurve3D test for complete coverage.

The rational curve tests cover D0, D1, and D2, but D3 is only tested for non-rational curves. Adding a D3 test for rational curves would provide symmetric coverage.

Do you want me to generate a D3_RationalCurve3D test following the existing pattern?

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Curve.hxx (1)

33-42: Consider using Standard_Real instead of double for consistency.

The Offset member uses double while the rest of OCCT typically uses Standard_Real. Although they're typically the same type, using Standard_Real maintains consistency with OCCT conventions.

 struct GeomAdaptor_OffsetCurveData
 {
   Handle(GeomAdaptor_Curve) BasisAdaptor; //!< Adaptor for basis curve
-  double                    Offset;       //!< Offset distance
+  Standard_Real             Offset;       //!< Offset distance
   gp_Dir                    Direction;    //!< Offset direction
 };
src/ModelingData/TKG2d/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx (1)

54-76: LGTM - consistent with 3D adaptor pattern.

The variant-based data storage pattern mirrors GeomAdaptor_Curve.hxx. The nested structs (OffsetData, BezierData, BSplineData) are well-documented with Doxygen comments. The mutable qualifier on Cache members is appropriate since caching doesn't affect logical const-ness.

Minor: Consider using Standard_Real instead of double for Offset (line 59) to maintain OCCT type consistency, similar to the 3D version.

src/FoundationClasses/TKMath/BSplSLib/BSplSLib_Cache.cxx (2)

41-76: Consider using Standard_Real (and guarding against zero span length) in local-param helpers.

Mostly consistency with OCCT conventions (and avoiding divide-by-zero UB if span length could ever be 0). Based on learnings, …


350-473: Local derivative mapping/scaling is readable; consider factoring shared layout logic.

Both D1Local and D2Local duplicate the “which param has higher degree” layout branching; a tiny helper to map indices could reduce maintenance risk.

src/FoundationClasses/TKMath/BSplCLib/BSplCLib_Cache.cxx (1)

26-50: Constructor overloads using unused parameters for type distinction.

The constructors use unused TColgp_Array1OfPnt2d and TColgp_Array1OfPnt parameters solely to distinguish between 2D and 3D variants. While this works, consider adding a brief comment explaining this design choice for clarity, as the /* only used to distinguish */ comments are helpful but could be more explicit about why this pattern was chosen over alternatives (like tag dispatch).

src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetCurve.cxx (1)

91-147: Nested offset unwrapping: good, but keep scalar-type guideline consistent
The loop correctly unwraps Geom2d_TrimmedCurve and flattens nested Geom2d_OffsetCurve by summing offsets (Line 98-114), and preserves trimming using original aUf/aUl (Line 139-146). Only concern here is the new double/bool local types vs repo conventions. Based on learnings, ...

src/ModelingData/TKG3d/Geom/Geom_RevolutionUtils.pxx (1)

42-70: Assumes theAxis is unit-length—document or enforce
ShiftPoint/RotatePoint use dot/cross as if theAxis is normalized; if callers ever pass non-unit gp_XYZ, rotation and projection magnitudes will be wrong. Consider either normalizing once (cost) or adding a clear contract comment / debug assert.

src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetUtils.pxx (1)

293-358: Type guideline drift (double/int/bool) in src/
This file is in src/** and uses double, int, bool extensively despite the repo guideline to prefer Standard_Real/Standard_Integer/Standard_Boolean. If this is a deliberate modernization, consider aligning the guideline; otherwise, adapt types here for consistency. Based on learnings, ...

src/ModelingData/TKG3d/Geom/Geom_OffsetSurfaceUtils.pxx (4)

74-90: Consider extracting the normalization logic to reduce duplication.

IsSingular and ComputeNormal share identical normalization code (lines 78-86 and 104-111). This could be extracted into a private helper.

+//! Normalizes derivatives if their magnitude exceeds 1.0 for numerical stability.
+inline void NormalizeDerivatives(gp_Vec& theD1U, gp_Vec& theD1V)
+{
+  double aD1UNorm2 = theD1U.SquareMagnitude();
+  double aD1VNorm2 = theD1V.SquareMagnitude();
+  if (aD1UNorm2 > 1.0)
+    theD1U /= std::sqrt(aD1UNorm2);
+  if (aD1VNorm2 > 1.0)
+    theD1V /= std::sqrt(aD1VNorm2);
+}

Also applies to: 98-120


250-262: CalculateD2 does not compute D2 derivatives.

The function name suggests it computes D2 but it delegates entirely to CalculateD1. The output parameters theD2U, theD2V, theD2UV are never modified - they are passed as const inputs. This is documented in the comments but could be confusing for callers. Consider renaming or adding a clearer note about why D2 is not computed in the non-singular case.


1144-1152: Redundant re-computation of D2 derivatives.

The D2U, D2V, D2UV were already computed from the D3 call at line 1035, but are re-fetched using DN at lines 1145-1147. The comment indicates this matches old behavior, but it adds unnecessary computation overhead.


1331-1348: Same redundant re-computation pattern in EvaluateD3.

Similar to EvaluateD2, the D2 and D3 derivatives are re-fetched via DN calls despite already being computed from the initial D3 call. If this is intentional for matching legacy behavior, consider adding a TODO to optimize in a future refactor.

src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.cxx (1)

383-386: Unused local variables.

Variables u1, u2, v1, v2 are declared and populated via myBasisSurf->Bounds() but never used afterward. Consider removing them or using std::ignore pattern if bounds are needed only for the call's side effects.

-    double u1, u2, v1, v2;
-    theT = false;
-    myBasisSurf->Bounds(u1, u2, v1, v2);
+    theT = false;
+    // Bounds are queried implicitly through knot arrays below

Also applies to: 445-448

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2919e1b and 15e1fe7.

📒 Files selected for processing (65)
  • src/FoundationClasses/TKMath/BSplCLib/BSplCLib_Cache.cxx (11 hunks)
  • src/FoundationClasses/TKMath/BSplCLib/BSplCLib_Cache.hxx (1 hunks)
  • src/FoundationClasses/TKMath/BSplSLib/BSplSLib_Cache.cxx (4 hunks)
  • src/FoundationClasses/TKMath/BSplSLib/BSplSLib_Cache.hxx (1 hunks)
  • src/FoundationClasses/TKMath/GTests/BSplCLib_Cache_Test.cxx (1 hunks)
  • src/FoundationClasses/TKMath/GTests/BSplSLib_Cache_Test.cxx (1 hunks)
  • src/FoundationClasses/TKMath/GTests/FILES.cmake (1 hunks)
  • src/ModelingAlgorithms/TKBool/TopOpeBRepTool/TopOpeBRepTool_GEOMETRY.cxx (1 hunks)
  • src/ModelingAlgorithms/TKShHealing/ShapeUpgrade/ShapeUpgrade_SplitSurface.cxx (1 hunks)
  • src/ModelingData/TKBRep/BRepAdaptor/BRepAdaptor_Curve2d.cxx (1 hunks)
  • src/ModelingData/TKG2d/Adaptor2d/Adaptor2d_OffsetCurve.cxx (5 hunks)
  • src/ModelingData/TKG2d/Geom2d/FILES.cmake (1 hunks)
  • src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetCurve.cxx (9 hunks)
  • src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetCurve.hxx (1 hunks)
  • src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetUtils.pxx (1 hunks)
  • src/ModelingData/TKG2d/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx (25 hunks)
  • src/ModelingData/TKG2d/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx (4 hunks)
  • src/ModelingData/TKG2d/Geom2dEvaluator/FILES.cmake (0 hunks)
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator.cxx (0 hunks)
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator.hxx (0 hunks)
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator_Curve.hxx (0 hunks)
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator_OffsetCurve.cxx (0 hunks)
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator_OffsetCurve.hxx (0 hunks)
  • src/ModelingData/TKG2d/PACKAGES.cmake (0 hunks)
  • src/ModelingData/TKG3d/Adaptor3d/Adaptor3d_HSurfaceTool.cxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/FILES.cmake (3 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_BSplineCurve.hxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_BSplineSurface.hxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_ExtrusionUtils.pxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OffsetCurve.cxx (9 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OffsetCurve.hxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OffsetCurveUtils.pxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx (13 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx (3 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OffsetSurfaceUtils.pxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.cxx (10 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.hxx (0 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.pxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_RevolutionUtils.pxx (1 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.cxx (7 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.hxx (0 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.cxx (7 hunks)
  • src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.hxx (2 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor.cxx (1 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Curve.cxx (10 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Curve.hxx (2 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx (31 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.hxx (4 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfLinearExtrusion.cxx (5 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfLinearExtrusion.hxx (2 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.cxx (5 hunks)
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.hxx (2 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/FILES.cmake (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_Curve.hxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetCurve.cxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetCurve.hxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.hxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_Surface.hxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.cxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.hxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.cxx (0 hunks)
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.hxx (0 hunks)
  • src/ModelingData/TKG3d/PACKAGES.cmake (0 hunks)
  • src/ModelingData/TKGeomBase/Extrema/Extrema_GenExtPS.cxx (1 hunks)
💤 Files with no reviewable changes (21)
  • src/ModelingData/TKG2d/PACKAGES.cmake
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator_Curve.hxx
  • src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.hxx
  • src/ModelingData/TKG3d/GeomEvaluator/FILES.cmake
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_Surface.hxx
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator_OffsetCurve.hxx
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator_OffsetCurve.cxx
  • src/ModelingData/TKG3d/PACKAGES.cmake
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.cxx
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.hxx
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_Curve.hxx
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator.hxx
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetCurve.hxx
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.cxx
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetCurve.cxx
  • src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.hxx
  • src/ModelingData/TKG2d/Geom2dEvaluator/FILES.cmake
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.hxx
  • src/ModelingData/TKG2d/Geom2dEvaluator/Geom2dEvaluator.cxx
  • src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.hxx
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-07-13T22:08:43.235Z
Learnt from: CR
Repo: dpasukhi/OCCT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-13T22:08:43.235Z
Learning: Applies to src/*/*/GTests/*.cxx : GTest files for a toolkit must be placed in src/Module/Toolkit/GTests/ and registered in FILES.cmake.

Applied to files:

  • src/FoundationClasses/TKMath/GTests/FILES.cmake
  • src/FoundationClasses/TKMath/GTests/BSplSLib_Cache_Test.cxx
  • src/ModelingData/TKG2d/Geom2d/FILES.cmake
  • src/FoundationClasses/TKMath/GTests/BSplCLib_Cache_Test.cxx
📚 Learning: 2025-07-13T22:08:43.235Z
Learnt from: CR
Repo: dpasukhi/OCCT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-13T22:08:43.235Z
Learning: Applies to src/*/*/FILES.cmake : When adding or removing files, you must edit the corresponding src/Module/Toolkit/FILES.cmake file.

Applied to files:

  • src/FoundationClasses/TKMath/GTests/FILES.cmake
  • src/ModelingData/TKG2d/Geom2d/FILES.cmake
  • src/ModelingData/TKG3d/Geom/FILES.cmake
📚 Learning: 2025-07-13T22:08:43.235Z
Learnt from: CR
Repo: dpasukhi/OCCT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-13T22:08:43.235Z
Learning: Applies to src/**/*.@(cxx|hxx) : Use the modern TopExp_Explorer constructor style: for (TopExp_Explorer anExp(theShape, TopAbs_FACE); anExp.More(); anExp.Next()) { ... }

Applied to files:

  • src/ModelingData/TKGeomBase/Extrema/Extrema_GenExtPS.cxx
  • src/ModelingData/TKG3d/Geom/FILES.cmake
  • src/ModelingAlgorithms/TKShHealing/ShapeUpgrade/ShapeUpgrade_SplitSurface.cxx
📚 Learning: 2025-07-13T22:08:43.235Z
Learnt from: CR
Repo: dpasukhi/OCCT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-13T22:08:43.235Z
Learning: Applies to src/**/*.@(cxx|hxx) : When downcasting topological shapes, ALWAYS use the TopoDS helper functions (e.g., TopoDS::Face(anExp.Current())) to avoid errors.

Applied to files:

  • src/ModelingData/TKGeomBase/Extrema/Extrema_GenExtPS.cxx
  • src/ModelingAlgorithms/TKBool/TopOpeBRepTool/TopOpeBRepTool_GEOMETRY.cxx
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfLinearExtrusion.cxx
  • src/ModelingData/TKG3d/Geom/FILES.cmake
  • src/ModelingAlgorithms/TKShHealing/ShapeUpgrade/ShapeUpgrade_SplitSurface.cxx
  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.cxx
📚 Learning: 2025-07-13T22:08:43.235Z
Learnt from: CR
Repo: dpasukhi/OCCT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-13T22:08:43.235Z
Learning: Applies to src/**/*.@(cxx|hxx) : ALWAYS use Handle(ClassName) for any class inheriting from Standard_Transient (e.g., Geom_*, Poly_*, AIS_*, V3d_*) instead of raw pointers.

Applied to files:

  • src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.hxx
  • src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx
  • src/ModelingData/TKG2d/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx
📚 Learning: 2025-07-13T22:08:43.235Z
Learnt from: CR
Repo: dpasukhi/OCCT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-13T22:08:43.235Z
Learning: Applies to src/*/*/FILES.cmake : After adding a file, ALWAYS update the corresponding src/Module/Toolkit/FILES.cmake file.

Applied to files:

  • src/ModelingData/TKG2d/Geom2d/FILES.cmake
  • src/ModelingData/TKG3d/Geom/FILES.cmake
📚 Learning: 2025-07-13T22:08:43.235Z
Learnt from: CR
Repo: dpasukhi/OCCT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-13T22:08:43.235Z
Learning: Applies to src/**/*.@(cxx|hxx) : Use Standard_Real for floating-point numbers, Standard_Integer for integer values, and Standard_Boolean for boolean values.

Applied to files:

  • src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx
  • src/ModelingData/TKG2d/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx
🧬 Code graph analysis (6)
src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx (1)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx (2)
  • theOther (96-113)
  • theOther (96-97)
src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.cxx (1)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx (4)
  • D0 (963-1003)
  • D0 (963-963)
  • DN (1313-1389)
  • DN (1313-1316)
src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.cxx (1)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx (9)
  • theOther (96-113)
  • theOther (96-97)
  • Handle (379-379)
  • Handle (1446-1446)
  • Handle (1506-1506)
  • UContinuity (463-517)
  • UContinuity (463-463)
  • VContinuity (521-575)
  • VContinuity (521-521)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx (3)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Curve.cxx (15)
  • Handle (201-201)
  • Handle (823-823)
  • ShallowCopy (64-86)
  • RebuildCache (516-546)
  • RebuildCache (516-516)
  • D0 (588-625)
  • D0 (588-588)
  • D1 (629-667)
  • D1 (629-629)
  • D2 (671-710)
  • D2 (671-671)
  • D3 (714-758)
  • D3 (714-718)
  • DN (762-801)
  • DN (762-762)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfLinearExtrusion.cxx (1)
  • ShallowCopy (55-89)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.cxx (1)
  • ShallowCopy (53-89)
src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetCurve.cxx (2)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Curve.cxx (10)
  • Handle (201-201)
  • Handle (823-823)
  • D0 (588-625)
  • D0 (588-588)
  • D1 (629-667)
  • D1 (629-629)
  • D2 (671-710)
  • D2 (671-671)
  • D3 (714-758)
  • D3 (714-718)
src/ModelingData/TKG3d/Geom/Geom_OffsetCurve.cxx (18)
  • Copy (47-50)
  • SetBasisCurve (131-201)
  • SetBasisCurve (131-132)
  • BasisCurve (205-208)
  • D0 (244-250)
  • D0 (244-244)
  • D1 (254-260)
  • D1 (254-254)
  • D2 (264-279)
  • D2 (264-267)
  • D3 (283-300)
  • D3 (283-287)
  • FirstParameter (323-326)
  • FirstParameter (323-323)
  • LastParameter (330-333)
  • LastParameter (330-330)
  • Offset (337-340)
  • Offset (337-337)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.cxx (1)
src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfLinearExtrusion.cxx (1)
  • BasisCurve (456-459)
🪛 Cppcheck (2.18.0)
src/FoundationClasses/TKMath/BSplSLib/BSplSLib_Cache.cxx

[error] 24-24: There is an unknown macro here somewhere. Configuration is required. If IMPLEMENT_STANDARD_RTTIEXT is a macro then please configure it.

(unknownMacro)

src/ModelingData/TKG3d/Geom/Geom_OffsetCurve.cxx

[error] 41-41: There is an unknown macro here somewhere. Configuration is required. If IMPLEMENT_STANDARD_RTTIEXT is a macro then please configure it.

(unknownMacro)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Prepare and Build on Ubuntu with Clang (x64)
  • GitHub Check: Prepare and Build on Windows with MSVC (x64)
  • GitHub Check: Prepare and Build on macOS with Clang (x64)
🔇 Additional comments (94)
src/ModelingAlgorithms/TKBool/TopOpeBRepTool/TopOpeBRepTool_GEOMETRY.cxx (1)

19-26: Good include hygiene: explicit Geom2dAdaptor_Curve.hxx matches actual usage.
This removes reliance on transitive includes for Geom2dAdaptor_Curve (used at Line 229 and Line 251) and should make builds more robust.

src/ModelingData/TKGeomBase/Extrema/Extrema_GenExtPS.cxx (1)

21-21: LGTM! Explicit includes improve maintainability.

The added includes make dependencies explicit for types that are already used throughout this file. This is a good refactoring practice that prevents potential build issues if transitive includes are removed from other headers.

Also applies to: 28-30

src/ModelingAlgorithms/TKShHealing/ShapeUpgrade/ShapeUpgrade_SplitSurface.cxx (1)

25-25: #include <gp_Ax1.hxx> is necessary and correctly placed.

The include is required because Geom_SurfaceOfRevolution.hxx only forward-declares gp_Ax1 but does not include its full definition. The code at lines 256 and 278 calls Surface->Axis(), which returns gp_Ax1 by value and passes it to the Geom_SurfaceOfRevolution constructor. Compiling without this explicit include would fail with an incomplete type error. The placement is appropriate, grouped with other geometry headers.

src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.hxx (1)

24-26: LGTM - Clean removal of evaluator dependency.

The removal of myEvaluator in favor of storing just the loc point aligns with the broader refactor to utility-based implementations. This reduces object overhead and moves evaluation logic to Geom_RevolutionUtils.

Also applies to: 332-332

src/ModelingData/TKG2d/Adaptor2d/Adaptor2d_OffsetCurve.cxx (1)

17-17: LGTM - Consistent migration to utility functions.

The transition from Geom2dEvaluator to Geom2d_OffsetUtils is applied uniformly across all derivative calculation paths (D0–D3). The API signatures appear preserved, making this a clean drop-in replacement.

Also applies to: 285-285, 309-309, 325-325, 345-345

src/FoundationClasses/TKMath/GTests/BSplSLib_Cache_Test.cxx (2)

36-55: Good test fixture structure.

The fixture and createFlatKnots helper are well-organized. The empty SetUp() override could be removed if not needed, but this is a minor style preference.


61-153: Solid test coverage for non-rational D0 evaluation.

The test properly validates cache correctness against direct BSplSLib::D0 evaluation across a parameter grid. The cache validity check before rebuild ensures correct behavior across span boundaries.

src/ModelingData/TKG3d/Geom/Geom_BSplineCurve.hxx (1)

811-819: LGTM - Consistent with Geom_BSplineSurface accessor pattern.

The new HArray* accessors mirror the surface API, providing efficient direct access for grid evaluation. Documentation properly notes that HArrayWeights() may be null for non-rational curves.

src/FoundationClasses/TKMath/BSplSLib/BSplSLib_Cache.hxx (2)

107-144: Well-documented local parameter evaluation API.

The D*Local methods are a useful optimization for cases where local parameters are pre-computed externally. The documentation clearly explains the parameter range and bypass behavior.


150-151: Good: Explicitly deleted copy semantics.

Explicitly deleting copy constructor and assignment operator prevents accidental copies of cache objects, which would be expensive and likely incorrect given the internal handle state.

src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.pxx (2)

38-63: Well-structured internal helper class with proper copy/move semantics.

The class follows the rule of five with explicit copy/move constructors and assignment operators. The use of std::array<bool, 4> for myAlong is cleaner than the traditional OCCT collection types for fixed-size boolean arrays.


74-81: Clear and efficient flag accessors.

The HasOscSurf(), IsAlongU(), and IsAlongV() methods provide clean read access to the internal state flags with intuitive semantics.

src/ModelingData/TKG3d/Geom/Geom_BSplineSurface.hxx (1)

1109-1120: LGTM - Well-documented const accessor methods for efficient access to internal storage.

The new HArray* accessors properly return const references to handles, enabling efficient access without copying. All methods are correctly marked const, preventing unintended modifications. The documentation correctly notes that HArrayWeights() returns null for non-rational surfaces.

src/ModelingData/TKG3d/Geom/Geom_OffsetCurveUtils.pxx (8)

1-25: Well-structured header with clear documentation.

The header includes appropriate license, necessary dependencies, and clear mathematical documentation explaining the offset curve formula P(u) = p(u) + Offset * N / ||N||.


44-59: LGTM!

The D0 calculation correctly computes the offset point using the cross product to find the normal direction, with appropriate zero-magnitude protection.


68-109: LGTM!

The D1 calculation implements the derivative formula correctly with two computation paths for numerical stability. The EUCLID-IS IICURV algorithm reference indicates this is a well-tested approach.


120-191: LGTM!

The D2 calculation correctly implements the second derivative formula with proper numerical stability paths and direction change handling at singular points.


229-260: Intentional mutability of R4 for fallback computation.

The non-const declaration of R4 (line 232) is intentional - it's reassigned in line 252 within the fallback branch, consistent with the pattern in CalculateD2.


385-419: LGTM!

The EvaluateD0 and EvaluateD1 template functions provide clean wrapper implementations that delegate to the corresponding Calculate* functions after obtaining necessary derivatives from the basis curve.


434-490: LGTM!

The EvaluateD2 and EvaluateD3 functions correctly handle singular points by detecting near-zero first derivatives and using AdjustDerivative to find valid tangent directions via Taylor series approximation.


503-524: LGTM!

The EvaluateDN function correctly routes derivative orders 1-3 to specialized implementations and properly returns false for unsupported orders, matching the documented constraint that N must be >= 1 and <= 3.

src/ModelingData/TKG3d/Adaptor3d/Adaptor3d_HSurfaceTool.cxx (1)

21-21: LGTM!

The added include for GeomAdaptor_Curve.hxx is necessary for the explicit instantiation at line 141, following the good practice of explicit includes over transitive dependencies.

src/ModelingData/TKG2d/Geom2d/FILES.cmake (1)

34-34: LGTM!

The new Geom2d_OffsetUtils.pxx is correctly added to the build system in alphabetical order. Based on learnings, updating FILES.cmake when adding files is required, and this is properly done.

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor.cxx (1)

20-25: LGTM!

The three added includes (Adaptor3d_Surface.hxx, GeomAbs_SurfaceType.hxx, Geom_BSplineSurface.hxx) are all necessary for functionality used in this file - making previously transitive dependencies explicit improves build reliability and clarity.

src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetCurve.hxx (1)

100-101: LGTM!

The copy constructor addition enables optimized deep copying without re-validating continuity constraints, which is appropriate since the source object has already been validated.

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.hxx (1)

22-22: Consistent type narrowing with SurfaceOfLinearExtrusion.

The changes mirror the same pattern applied to GeomAdaptor_SurfaceOfLinearExtrusion. The internal storage uses the concrete GeomAdaptor_Curve type while maintaining the public API contract via the base type.

Also applies to: 178-181

src/FoundationClasses/TKMath/GTests/BSplCLib_Cache_Test.cxx (1)

38-57: Well-structured test fixture and helper.

The createFlatKnots helper correctly expands knots by their multiplicities, and the fixture provides a clean setup for the test cases.

src/FoundationClasses/TKMath/GTests/FILES.cmake (1)

10-11: LGTM! Test files correctly registered in alphabetical order.

Both BSplCLib_Cache_Test.cxx and BSplSLib_Cache_Test.cxx exist in src/FoundationClasses/TKMath/GTests/ and are properly registered in the FILES.cmake file.

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfLinearExtrusion.hxx (1)

22-22: Type narrowing for internal storage is appropriate.

The change from Handle(Adaptor3d_Curve) to Handle(GeomAdaptor_Curve) for the private member aligns with the broader refactor. The public Load() method still accepts Handle(Adaptor3d_Curve), so the implementation must perform a DownCast.

Also applies to: 165-167

src/ModelingData/TKG3d/Geom/FILES.cmake (1)

43-43: New utility files properly registered.

The new .pxx utility files for extrusion, offset, and revolution computations are correctly added in alphabetical order to FILES.cmake. These replace the evaluator-based implementations as per the PR objectives.

Also applies to: 55-58, 67-67

src/ModelingData/TKBRep/BRepAdaptor/BRepAdaptor_Curve2d.cxx (1)

46-67: Check if myCurveData variant has additional alternatives beyond OffsetData, BSplineData, and BezierData.

The code dispatches on three variant types but lacks an else clause. If the variant includes std::monostate or other unhandled alternatives, the copied object's myCurveData would remain default-initialized. Confirm the variant definition includes only these three types, or add an else clause to handle unexpected states defensively.

src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.cxx (4)

23-23: Consider using angle brackets for consistency.

The include uses quoted form "Geom_RevolutionUtils.pxx" while other includes in this file use angle brackets <...>. This is typically intentional for private/internal implementation files (.pxx), so this is acceptable if that's the convention for OCCT private headers.


192-196: LGTM!

The simplified SetBasisCurve cleanly removes evaluator dependency. The basis curve is properly copied and continuity is captured.


221-224: LGTM!

Clean delegation to Geom_RevolutionUtils::D0 with explicit parameter passing.


295-302: LGTM!

The DN method properly validates input parameters before delegation. The condition Nu + Nv < 1 || Nu < 0 || Nv < 0 correctly ensures at least one derivative order and non-negative indices.

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Curve.hxx (1)

266-268: LGTM!

The private member reorganization cleanly separates B-spline caching (myBSplineCurve, myCurveCache) from the new variant-based curve-specific data (myCurveData). The comments are clear and the structure is well-organized.

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.cxx (2)

53-89: LGTM!

The ShallowCopy implementation properly handles the variant-based data model. It correctly:

  1. Shallow copies the basis curve
  2. Copies all scalar/simple members
  3. Properly extracts and reconstructs RevolutionData with a shallow copy of the nested BasisCurve

108-114: LGTM!

Clean population of RevolutionData variant with axis location and direction extracted from the gp_Ax1. The use of std::move is appropriate for transferring the struct into the variant.

src/ModelingData/TKG2d/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx (1)

40-42: LGTM!

Moving the forward declaration and DEFINE_STANDARD_HANDLE before the class definition follows OCCT conventions and is necessary since OffsetData references Handle(Geom2dAdaptor_Curve).

src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx (2)

394-398: LGTM - Modern smart pointer usage.

Replacing Handle(Geom_OsculatingSurface) with std::unique_ptr<Geom_OsculatingSurface> is a good modernization. This provides:

  • Clear ownership semantics (exclusive ownership)
  • Automatic cleanup
  • Reduced overhead compared to reference-counted handles when sharing isn't needed

The forward declaration pattern with unique_ptr is properly set up with the explicit destructor.


111-112: Destructor is required for unique_ptr with forward-declared type.

The explicit destructor declaration is necessary because std::unique_ptr<Geom_OsculatingSurface> requires the complete type at destruction. The destructor is properly defined in Geom_OffsetSurface.cxx:103 as = default, which is the correct implementation for this pattern.

src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.cxx (3)

138-185: Delegation to Geom_ExtrusionUtils for D0–D3 is clean.


21-21: The .pxx inclusion is ODR-safe. Geom_ExtrusionUtils.pxx is header-guarded (#ifndef _Geom_ExtrusionUtils_HeaderFile) and contains only inline template functions in a namespace, making it suitable for multiple inclusions across translation units without linker conflicts.


68-74: Constructor/SetBasisCurve simplification is correct—no null-handling issue found. All call sites pass non-null Handle(Geom_Curve) objects, and the identical pattern is used in Geom_SurfaceOfRevolution::SetBasisCurve() without null checks. The implicit invariant is that C must be non-null.

src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx (2)

1018-1029: Osculating-surface presence checks are now simpler and correct.


312-483: New singular-evaluation routing is clearer and the early-return on equivSurf is good. Exception handling for singularities is appropriate: Geom_UndefinedValue for D0 and Geom_UndefinedDerivative for D1/D2/D3/DN. The implementation uses CSLib::Normal for robust singularity detection with retry logic via ShiftPoint, and properly handles osculating surfaces. However, the legacy GeomEvaluator_OffsetSurface code is not available in the repository to verify direct behavioral equivalence.

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfLinearExtrusion.cxx (2)

191-200: VTrim DownCast looks OK if BasisCurve is guaranteed GeomAdaptor_Curve (but same caveat).


55-89: [rewritten comment]
[classification tag]

src/FoundationClasses/TKMath/BSplSLib/BSplSLib_Cache.cxx (3)

90-226: EvaluatePolynomials() structure + rational temp buffer approach looks correct and safer than in-place.

The non-rational “compute only what’s needed” optimization for rows 1/2 matches the derivative terms you later consume in D1/D2 paths.


300-346: D0 → D0Local refactor is clean and keeps rational handling intact.


476-584: D1/D2 reuse of the same inverse factors for local-param conversion and scaling is a good consistency win.

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Curve.cxx (1)

73-83: Variant-based offset-curve data copy/reset/load looks consistent.

Also applies to: 181-244

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.hxx (3)

49-102: Well-designed variant-based data model.

The new SurfaceDataVariant and associated data structures provide a clean, type-safe approach to storing surface-specific evaluation data. The use of std::monostate as the first variant alternative ensures default-constructibility.

A few observations:

  • OsculatingSurfaceDeleter correctly handles the incomplete type Geom_OsculatingSurface in the header.
  • OffsetData explicitly defines copy semantics with Standard_EXPORT, which is necessary given the unique_ptr member.

180-194: LGTM!

The Bounds() method provides a convenient accessor that delegates to the existing parameter methods. This is a useful addition for clients that need all parametric bounds at once.


421-422: Clean member data organization.

The variant-based mySurfaceData member consolidates what were previously scattered per-type caches and evaluators into a single, type-safe storage mechanism.

src/FoundationClasses/TKMath/BSplCLib/BSplCLib_Cache.cxx (3)

119-184: Sound derivative calculation implementation.

The refactored derivative calculation correctly:

  1. Normalizes parameters via periodic normalization and span scaling
  2. Uses division by SpanLength for unnormalization (better numerical stability for small spans)
  3. Handles both rational and non-rational cases appropriately

The temporary buffer sizing of 16 elements correctly covers the maximum case of 4 derivative levels × 4 dimensions (3D + weight).


220-237: LGTM!

D0Local correctly evaluates the point using the pre-computed local parameter, avoiding redundant normalization when the caller has already computed it.


265-369: LGTM!

The D1Local, D2Local, and D3Local methods follow a consistent pattern with correctly sized local arrays and proper index calculations for extracting derivative vectors.

src/ModelingData/TKG3d/Geom/Geom_OffsetCurve.cxx (5)

43-43: Static analysis hint is a false positive.

The IMPLEMENT_STANDARD_RTTIEXT macro is a standard OCCT macro for runtime type information. Cppcheck reports it as unknown because it lacks OCCT-specific configuration.


58-65: LGTM!

The copy constructor correctly performs a deep copy of the basis curve while avoiding redundant validation, as the source curve is already validated.


152-166: Verify direction normalization after vector combination.

When combining offset directions, the resulting Vdir vector is set directly to direction (a gp_Dir). While gp_Dir::SetXYZ() normalizes the input, this could fail if Vdir has zero magnitude (when the two offset directions cancel out perfectly).

Consider adding a check for this edge case:

       gp_Vec Vdir(PrevOff * V1 + offsetValue * V2);

+      if (Vdir.Magnitude() < gp::Resolution())
+      {
+        // Offsets cancel out - result is effectively no offset
+        offsetValue = 0.0;
+        // Keep original direction
+      }
+      else if (offsetValue >= 0.)
-      if (offsetValue >= 0.)
       {

244-300: LGTM!

The derivative methods consistently delegate to the utility functions with proper error handling. The error messages clearly identify which derivative level failed.


304-319: LGTM!

The DN method correctly distinguishes between capability limitations (N > 3) and computation failures, throwing appropriate exception types for each case.

src/FoundationClasses/TKMath/BSplCLib/BSplCLib_Cache.hxx (3)

125-158: Well-documented local-parameter API.

The new D0Local, D1Local, D2Local, and D3Local methods are well-documented with clear explanations of the expected local parameter format: (Param - SpanStart) / SpanLength. This optimization path is valuable for callers who need to evaluate multiple times with the same local parameter.


163-179: LGTM!

The protected helper methods provide the implementation backbone for both global and local parameter evaluation paths, with clear documentation of the derivative array sizing requirements.


182-183: LGTM!

Explicitly deleting copy operations is appropriate for a cache class, preventing accidental expensive copies and enforcing handle-based sharing semantics.

src/ModelingData/TKG3d/Geom/Geom_ExtrusionUtils.pxx (4)

31-50: LGTM!

The D0 function correctly implements the extrusion surface formula P(U,V) = C(U) + V * Direction.


61-73: LGTM!

The first derivatives are correctly computed: ∂P/∂U = C'(U) from the basis curve, and ∂P/∂V = Direction (constant).


87-146: LGTM!

The second and third derivative implementations are mathematically correct. Since extrusion is linear in V, all second and higher derivatives involving V are zero, and all mixed derivatives involving V vanish.


156-168: LGTM!

The DN function correctly handles the three cases:

  1. Pure U derivatives → delegate to basis curve
  2. First V derivative (0,1) → return the extrusion direction
  3. All other cases → zero vector (mathematically correct for linear extrusion)
src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetCurve.cxx (4)

56-62: New constructor flag wiring looks correct
Geom2d_OffsetCurve(..., isTheNotCheckC0) flows into SetBasisCurve(..., isTheNotCheckC0) as expected (no partial init).


66-72: Copy ctor skips validation—ensure this is intentional for invariants
Copy now deep-copies basisCurve without re-running SetBasisCurve validation. That’s fine if basisCurve is guaranteed valid for all constructed objects, but it removes a safety net for any previously-allowed “repair on copy” behavior.


198-266: Evaluator removal: D0–D3/DN error paths are consistent and aligned with 3D
Routing D0–D3 via Geom2d_OffsetUtils::EvaluateD* and throwing Standard_NullValue on failure is consistent; DN cleanly gates N>3 as Standard_NotImplemented and keeps “compute failure” as Standard_NullValue.


323-327: Transform scaling: verify mirror/negative scale semantics
Scaling offsetValue *= std::abs(T.ScaleFactor()) matches the “distance scales by |s|” rule, but if 2D mirroring is expected to flip the offset side for orientation-dependent offsets, this will preserve side. Please confirm expected OCCT behavior for mirrored transforms on 2D offsets.

src/ModelingData/TKG3d/Geom/Geom_RevolutionUtils.pxx (1)

80-315: D0–D3 derivative propagation looks coherent (Rodrigues-style)
The decomposition into perpendicular shift + cross term and then reusing it for U-derivatives is consistent across D1/D2/D3 (not seeing sign mistakes).

src/ModelingData/TKG2d/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx (3)

65-98: ShallowCopy variant cloning looks OK (but Bezier cache policy differs)
Offset shallow-copy properly recreates nested basis adaptor via ShallowCopy(); BSpline copies handle but not cache (rebuild-on-demand) which is consistent with later cache usage.


565-599: Cache build logic: good separation per-variant
Moving caches into BezierData.Cache and BSplineData.Cache and rebuilding on demand is clean and avoids cross-type stale state.


643-890: Offset evaluation + DN gating matches 2D offset curve behavior
Using Geom2d_OffsetUtils::EvaluateD0..D3/DN with Standard_NullValue and Standard_NotImplemented (N>3) is consistent and predictable.

src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetUtils.pxx (1)

42-279: Math port looks consistent; singular-point adjustment is well-scoped
The CalculateD0..D3 routines are cohesive and AdjustDerivative() only kicks in when D1 is near-zero, matching the intent for singular handling.

src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx (2)

84-113: OffsetData deep-copy of OsculatingSurface is correct
Copy ctor/assignment correctly clones Geom_OsculatingSurface and resets on absence, avoiding shared mutable state.


26-30: .pxx includes via relative paths: verify build portability
Including ../Geom/*.pxx from this TU is convenient, but it can be brittle across build systems / include-path setups. Please confirm this matches the project’s existing pattern for template utilities (and doesn’t break IDE/indexer or unity builds).

src/ModelingData/TKG3d/Geom/Geom_OffsetSurfaceUtils.pxx (6)

1-28: LGTM on includes and header structure.

The include set is appropriate for the geometric computations, and the header guard follows standard convention.


47-58: LGTM on OsculatingInfo struct.

Clean struct with appropriate defaults and helper methods for osculating surface handling.


280-391: LGTM on ComputeDerivatives template.

The template handles both osculating and non-osculating paths correctly, with proper array bounds management for different derivative orders.


408-480: LGTM on ReplaceDerivative template.

Good handling of the CSLib_InfinityOfSolutions case by stepping away from the singular point. The bidirectional search (aStepSign = -1 and +1) with bounds checking is appropriate.


582-623: LGTM on ShiftPoint function.

The iterative shifting towards the parametric center with proper handling of periodicity and singularity direction is well implemented.


653-778: Verify the infinite loop termination in EvaluateD0.

The for (;;) loop relies on ShiftPoint returning false to terminate when the center is overpassed. While ShiftPoint does have this exit condition, ensure that edge cases (e.g., very small domains) don't cause excessive iterations.

src/ModelingData/TKG3d/Geom/Geom_OsculatingSurface.cxx (7)

14-14: New include for implementation file.

The .pxx extension suggests this is an internal implementation header containing the class definition that was previously in a separate .hxx file. This is a common pattern for OCCT.


33-45: LGTM on constructors.

Default and parameterized constructors properly initialize the myAlong array using aggregate initialization.


61-71: LGTM on move constructor.

Properly moves members and resets the moved-from object state to a valid empty state.


91-107: LGTM on move assignment operator.

Includes self-assignment check and properly resets the moved-from object.


177-178: Clearing flags when both U and V are along singular directions.

The logic clears osculating flags when surface is singular along both U and V, which is appropriate since osculating surfaces cannot be built in this degenerate case.


781-783: LGTM on clearOsculFlags implementation.

Using std::array::fill(false) is clean and idiomatic.


111-370: Init function properly reinitializes all state.

The Init function correctly clears all containers and flags before rebuilding the osculating surfaces. The zero-based indexing for myAlong[0..3] is consistently used throughout.

Comment on lines +22 to +23
#include <utility>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add missing <algorithm> include (uses std::max, std::min, std::minmax).

This file uses std::max, std::min, and std::minmax, but only adds <utility>. Don’t rely on transitive includes.

 #include <NCollection_LocalArray.hxx>
 
 #include <TColgp_HArray2OfPnt.hxx>
 #include <TColStd_HArray2OfReal.hxx>
 
+#include <algorithm>
 #include <utility>

Also applies to: 26-228

🤖 Prompt for AI Agents
In src/FoundationClasses/TKMath/BSplSLib/BSplSLib_Cache.cxx around lines 22-23
(and generally lines 26-228), the file uses std::max, std::min and std::minmax
but only includes <utility>; add #include <algorithm> near the top of the file
to directly provide these function templates (don’t rely on transitive
includes), then recompile to ensure no other missing standard headers remain.

Comment on lines +503 to +515
// Compare point
EXPECT_NEAR(aCachePnt.X(), aDirectPnt.X(), THE_TOLERANCE) << "D3 point X mismatch at u=" << u;

// Compare tangent
EXPECT_NEAR(aCacheTan.X(), aDirectTan.X(), THE_TOLERANCE) << "D3 tangent X mismatch at u=" << u;

// Compare curvature
EXPECT_NEAR(aCacheCurv.X(), aDirectCurv.X(), THE_TOLERANCE)
<< "D3 curvature X mismatch at u=" << u;

// Compare torsion
EXPECT_NEAR(aCacheTors.X(), aDirectTors.X(), THE_TOLERANCE)
<< "D3 torsion X mismatch at u=" << u;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

D3 test only validates X components.

Unlike the D0, D1, and D2 tests which validate all X, Y, Z components, the D3 test only checks the X component for point, tangent, curvature, and torsion. This leaves Y and Z components unverified.

     // Compare point
     EXPECT_NEAR(aCachePnt.X(), aDirectPnt.X(), THE_TOLERANCE) << "D3 point X mismatch at u=" << u;
+    EXPECT_NEAR(aCachePnt.Y(), aDirectPnt.Y(), THE_TOLERANCE) << "D3 point Y mismatch at u=" << u;
+    EXPECT_NEAR(aCachePnt.Z(), aDirectPnt.Z(), THE_TOLERANCE) << "D3 point Z mismatch at u=" << u;
 
     // Compare tangent
     EXPECT_NEAR(aCacheTan.X(), aDirectTan.X(), THE_TOLERANCE) << "D3 tangent X mismatch at u=" << u;
+    EXPECT_NEAR(aCacheTan.Y(), aDirectTan.Y(), THE_TOLERANCE) << "D3 tangent Y mismatch at u=" << u;
+    EXPECT_NEAR(aCacheTan.Z(), aDirectTan.Z(), THE_TOLERANCE) << "D3 tangent Z mismatch at u=" << u;
 
     // Compare curvature
     EXPECT_NEAR(aCacheCurv.X(), aDirectCurv.X(), THE_TOLERANCE)
       << "D3 curvature X mismatch at u=" << u;
+    EXPECT_NEAR(aCacheCurv.Y(), aDirectCurv.Y(), THE_TOLERANCE)
+      << "D3 curvature Y mismatch at u=" << u;
+    EXPECT_NEAR(aCacheCurv.Z(), aDirectCurv.Z(), THE_TOLERANCE)
+      << "D3 curvature Z mismatch at u=" << u;
 
     // Compare torsion
     EXPECT_NEAR(aCacheTors.X(), aDirectTors.X(), THE_TOLERANCE)
       << "D3 torsion X mismatch at u=" << u;
+    EXPECT_NEAR(aCacheTors.Y(), aDirectTors.Y(), THE_TOLERANCE)
+      << "D3 torsion Y mismatch at u=" << u;
+    EXPECT_NEAR(aCacheTors.Z(), aDirectTors.Z(), THE_TOLERANCE)
+      << "D3 torsion Z mismatch at u=" << u;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Compare point
EXPECT_NEAR(aCachePnt.X(), aDirectPnt.X(), THE_TOLERANCE) << "D3 point X mismatch at u=" << u;
// Compare tangent
EXPECT_NEAR(aCacheTan.X(), aDirectTan.X(), THE_TOLERANCE) << "D3 tangent X mismatch at u=" << u;
// Compare curvature
EXPECT_NEAR(aCacheCurv.X(), aDirectCurv.X(), THE_TOLERANCE)
<< "D3 curvature X mismatch at u=" << u;
// Compare torsion
EXPECT_NEAR(aCacheTors.X(), aDirectTors.X(), THE_TOLERANCE)
<< "D3 torsion X mismatch at u=" << u;
// Compare point
EXPECT_NEAR(aCachePnt.X(), aDirectPnt.X(), THE_TOLERANCE) << "D3 point X mismatch at u=" << u;
EXPECT_NEAR(aCachePnt.Y(), aDirectPnt.Y(), THE_TOLERANCE) << "D3 point Y mismatch at u=" << u;
EXPECT_NEAR(aCachePnt.Z(), aDirectPnt.Z(), THE_TOLERANCE) << "D3 point Z mismatch at u=" << u;
// Compare tangent
EXPECT_NEAR(aCacheTan.X(), aDirectTan.X(), THE_TOLERANCE) << "D3 tangent X mismatch at u=" << u;
EXPECT_NEAR(aCacheTan.Y(), aDirectTan.Y(), THE_TOLERANCE) << "D3 tangent Y mismatch at u=" << u;
EXPECT_NEAR(aCacheTan.Z(), aDirectTan.Z(), THE_TOLERANCE) << "D3 tangent Z mismatch at u=" << u;
// Compare curvature
EXPECT_NEAR(aCacheCurv.X(), aDirectCurv.X(), THE_TOLERANCE)
<< "D3 curvature X mismatch at u=" << u;
EXPECT_NEAR(aCacheCurv.Y(), aDirectCurv.Y(), THE_TOLERANCE)
<< "D3 curvature Y mismatch at u=" << u;
EXPECT_NEAR(aCacheCurv.Z(), aDirectCurv.Z(), THE_TOLERANCE)
<< "D3 curvature Z mismatch at u=" << u;
// Compare torsion
EXPECT_NEAR(aCacheTors.X(), aDirectTors.X(), THE_TOLERANCE)
<< "D3 torsion X mismatch at u=" << u;
EXPECT_NEAR(aCacheTors.Y(), aDirectTors.Y(), THE_TOLERANCE)
<< "D3 torsion Y mismatch at u=" << u;
EXPECT_NEAR(aCacheTors.Z(), aDirectTors.Z(), THE_TOLERANCE)
<< "D3 torsion Z mismatch at u=" << u;
🤖 Prompt for AI Agents
In src/FoundationClasses/TKMath/GTests/BSplCLib_Cache_Test.cxx around lines 503
to 515 the D3 test currently asserts only the X component for point, tangent,
curvature and torsion; add EXPECT_NEAR assertions for the Y() and Z() components
for each of aCachePnt vs aDirectPnt, aCacheTan vs aDirectTan, aCacheCurv vs
aDirectCurv and aCacheTors vs aDirectTors using THE_TOLERANCE and the same
descriptive failure messages (e.g. "D3 point Y mismatch at u=", "D3 point Z
mismatch at u=", etc.) so all three components are validated consistently with
D0–D2 tests.

Comment on lines +24 to +27
#include <Geom2d_OffsetUtils.pxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <Standard_NullValue.hxx>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing direct include for std::abs + OCCT scalar type consistency drift
Line 326 uses std::abs but this TU doesn’t include <cmath> explicitly (relying on transitive includes is fragile). Also, switching local arithmetic from Standard_Real/Standard_Boolean to double/bool (Line 41, Line 94, Line 96, Line 118) conflicts with the repo guideline. Based on learnings, ...

@@
 #include <Geom2d_UndefinedDerivative.hxx>
 #include <Standard_NullValue.hxx>
+#include <cmath>
@@
-static const double MyAngularToleranceForG1 = Precision::Angular();
+static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();

Also applies to: 41-41

🤖 Prompt for AI Agents
In src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetCurve.cxx around lines 24 and
41/94/96/118, add an explicit #include <cmath> (or <math.h>) to ensure std::abs
is available without relying on transitive includes, and change any local uses
of native types back to OCCT scalar types: replace double with Standard_Real and
bool with Standard_Boolean at the mentioned lines so the translation unit
remains consistent with the project’s scalar type conventions; ensure calls to
absolute value use std::abs with Standard_Real or the appropriate OCCT helpers
if preferred.

Comment on lines +17 to +24
#include <gp.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_XY.hxx>

#include <cmath>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Header is not self-contained: missing <algorithm> (and possibly OCCT Real defs)*
This header uses std::min/std::max (Line 320, Line 343-344) but doesn’t include <algorithm>, which can break builds depending on include order. It also uses RealFirst()/RealLast() (Line 311) without a direct include guaranteeing those are declared.

@@
 #include <gp_XY.hxx>
 
+#include <algorithm>
 #include <cmath>
+
+#include <Standard_Real.hxx>

Also applies to: 281-359

🤖 Prompt for AI Agents
In src/ModelingData/TKG2d/Geom2d/Geom2d_OffsetUtils.pxx around lines 17–24 (and
affecting usage around 281–359/lines ~311/320/343–344), this file uses
std::min/std::max and RealFirst()/RealLast() but doesn't include the headers
that guarantee those symbols; add #include <algorithm> to provide
std::min/std::max and add the appropriate OCCT header that declares
RealFirst/RealLast (e.g., the OCCT Standard Real typedef/header used in the
project such as Standard_Real.hxx or the header your codebase uses for OCCT Real
definitions) to the top include block so the file is self-contained and builds
regardless of include order.

Comment on lines +366 to +370
gp_Vec* aDeriv[3] = {&theD2, &theD3, &theD4};
for (int i = 1; i < theMaxDerivative; i++)
{
*(aDeriv[i - 1]) = theCurve.DN(theU, anIndex + i) * aSign;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential out-of-bounds access if theMaxDerivative > 4.

The aDeriv array has only 3 elements, but if theMaxDerivative > 4 is passed, the loop would attempt to access aDeriv[3] or beyond, causing undefined behavior. While current callers only use values 3 or 4, the function signature doesn't enforce this constraint.

Consider adding a bounds check or static assertion:

+  // theMaxDerivative must be 3 or 4
+  Standard_ASSERT_RAISE(theMaxDerivative >= 3 && theMaxDerivative <= 4,
+                        "theMaxDerivative must be 3 or 4");
+
   theD1             = V * aSign;
   gp_Vec* aDeriv[3] = {&theD2, &theD3, &theD4};

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/ModelingData/TKG3d/Geom/Geom_OffsetCurveUtils.pxx around lines 366 to
370, the loop writes into aDeriv which is a 3-element array, causing
out-of-bounds access when theMaxDerivative > 4; add a guard that validates or
clamps theMaxDerivative to the array capacity before the loop (e.g., compute a
safeMax = std::min(theMaxDerivative, 4) or explicitly check and throw/log on
unsupported values) and use safeMax in the for-loop so only indices 1..4 are
accessed, or alternatively expand the array to match the documented/allowed
maximum if larger derivatives must be supported.

#include <Standard_Type.hxx>

#include <GeomAbs_Shape.hxx>
#include <Geom_BSplineSurface.hxx>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how Geom_BSplineSurface is used in this header
rg -n "Geom_BSplineSurface" src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx -A 2 -B 2

Repository: dpasukhi/OCCT

Length of output: 729


🏁 Script executed:

#!/bin/bash
# Check the structure of the header file - are there inline implementations?
# First, let's see the file size and general structure
wc -l src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx

# Check if there are method implementations (indicated by { }) in the header
grep -n "^{" src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx | head -5

# Get the lines around the method declarations to see if they have bodies
sed -n '369,390p' src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx

Repository: dpasukhi/OCCT

Length of output: 1160


🏁 Script executed:

#!/bin/bash
# Verify that these are not inline implementations by checking for opening braces
# on the method declaration lines
sed -n '368,382p' src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx | grep -E "(Standard_Boolean|Handle)" | head -10

Repository: dpasukhi/OCCT

Length of output: 361


Remove #include <Geom_BSplineSurface.hxx> and use a forward declaration instead.

Geom_BSplineSurface is used only in method parameter signatures (Handle(Geom_BSplineSurface)&) on lines 371 and 382, both of which are non-inline exported methods. A forward declaration is sufficient since the template instantiation occurs in the implementation file, not in this header.

🤖 Prompt for AI Agents
In src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx around line 24 (affects
usage at lines 371 and 382), remove the #include <Geom_BSplineSurface.hxx> and
replace it with a forward declaration "class Geom_BSplineSurface;" near the top
of the header so Handle(Geom_BSplineSurface)& can be used in the non-inline
exported method signatures; keep the actual #include <Geom_BSplineSurface.hxx>
only in the corresponding .cxx implementation file where the
template/instantiation occurs.

Comment on lines +129 to +148
inline gp_Vec ComputeDNormalU(const gp_Vec& theD1U,
const gp_Vec& theD1V,
const gp_Vec& theD2U,
const gp_Vec& theD2UV,
const gp_Vec& theNormal)
{
double aScale = (theD1U ^ theD1V).Dot(theNormal);

gp_Vec aN1U;
aN1U.SetX(theD2U.Y() * theD1V.Z() + theD1U.Y() * theD2UV.Z() - theD2U.Z() * theD1V.Y()
- theD1U.Z() * theD2UV.Y());
aN1U.SetY(-(theD2U.X() * theD1V.Z() + theD1U.X() * theD2UV.Z() - theD2U.Z() * theD1V.X()
- theD1U.Z() * theD2UV.X()));
aN1U.SetZ(theD2U.X() * theD1V.Y() + theD1U.X() * theD2UV.Y() - theD2U.Y() * theD1V.X()
- theD1U.Y() * theD2UV.X());
double aScaleU = aN1U.Dot(theNormal);
aN1U.Subtract(aScaleU * theNormal);
aN1U /= aScale;

return aN1U;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n -A5 -B5 'ComputeDNormalU|ComputeDNormalV' --type cpp

Repository: dpasukhi/OCCT

Length of output: 39


🏁 Script executed:

rg -n -A5 -B5 'ComputeDNormalU|ComputeDNormalV'

Repository: dpasukhi/OCCT

Length of output: 3506


🏁 Script executed:

sed -n '180,240p' src/ModelingData/TKG3d/Geom/Geom_OffsetSurfaceUtils.pxx

Repository: dpasukhi/OCCT

Length of output: 2543


🏁 Script executed:

rg -n -A10 'inline.*ComputeNormal' src/ModelingData/TKG3d/Geom/Geom_OffsetSurfaceUtils.pxx

Repository: dpasukhi/OCCT

Length of output: 544


🏁 Script executed:

sed -n '98,122p' src/ModelingData/TKG3d/Geom/Geom_OffsetSurfaceUtils.pxx

Repository: dpasukhi/OCCT

Length of output: 803


Document the precondition that ComputeDNormalU/V must only be called after successful ComputeNormal check.

While CalculateD1 properly guards these calls with a ComputeNormal check that returns false for singular cases, ComputeDNormalU and ComputeDNormalV have no such safeguard in their own implementations. The division by aScale at line 146 assumes non-zero magnitude, but this assumption is implicit rather than documented. Add a precondition note to both functions clarifying they require a non-singular surface (valid normal from ComputeNormal), or add a runtime check for aScale magnitude to improve robustness.

🤖 Prompt for AI Agents
In src/ModelingData/TKG3d/Geom/Geom_OffsetSurfaceUtils.pxx around lines 129 to
148, ComputeDNormalU (and similarly ComputeDNormalV) assumes aScale != 0 (normal
is valid) but does not document this precondition nor guard against division by
zero; update both functions to either: 1) add a clear precondition comment at
the top stating they must only be called after a successful ComputeNormal
(non-singular surface), or 2) add a runtime check on fabs(aScale) against a
small epsilon and handle the singular case (e.g., return a zero vector or an
appropriate default and/or signal error) to avoid division by zero and make
behavior explicit. Ensure the chosen approach is applied to both ComputeDNormalU
and ComputeDNormalV and keep the handling consistent with surrounding code
patterns (logging/return conventions).

Comment on lines 327 to 392
template <typename CurveType>
inline gp_Vec DN(const double theU,
const double theV,
const CurveType& theBasis,
const gp_XYZ& theLoc,
const gp_XYZ& theAxis,
const int theDerU,
const int theDerV)
{
const double aSin = std::sin(theU);
const double aCos = std::cos(theU);

gp_XYZ aDV;
gp_XYZ aPntXYZ; // Store original point to avoid redundant curve evaluation
if (theDerV == 0)
{
gp_Pnt aP;
theBasis.D0(theV, aP);
aPntXYZ = aP.XYZ();
aDV = aPntXYZ - theLoc;
}
else
{
aDV = theBasis.DN(theV, theDerV).XYZ();
}

gp_XYZ aResult;
if (theDerU == 0)
{
// Just rotate the curve derivative
RotatePoint(aSin, aCos, gp_XYZ(0, 0, 0), theAxis, aDV, aResult);
}
else
{
// Compute shift and cross for the V-derivative vector
gp_XYZ aShift;
if (theDerV == 0)
{
ShiftPoint(theLoc, theAxis, aPntXYZ, aShift);
}
else
{
ShiftPoint(gp_XYZ(0, 0, 0), theAxis, aDV, aShift);
}
gp_XYZ aCross = theAxis.Crossed(aShift);

// Apply U-derivative pattern (periodic with period 4)
switch (theDerU % 4)
{
case 1: // -sin*shift + cos*cross
aResult.SetLinearForm(-aSin, aShift, aCos, aCross);
break;
case 2: // -cos*shift - sin*cross
aResult.SetLinearForm(-aCos, aShift, -aSin, aCross);
break;
case 3: // sin*shift - cos*cross
aResult.SetLinearForm(aSin, aShift, -aCos, aCross);
break;
case 0: // cos*shift + sin*cross
aResult.SetLinearForm(aCos, aShift, aSin, aCross);
break;
}
}

return gp_Vec(aResult);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

DN() likely wrong/undefined for (theDerU,theDerV)==(0,0)
When theDerV==0, you set aDV = P - theLoc and for theDerU==0 return a rotated vector, not the surface point. If any call site uses DN(U,V,0,0) as “value”, this will silently return the wrong thing. Suggest guarding: reject (0,0) or define behavior explicitly.

@@
 inline gp_Vec DN(..., const int theDerU, const int theDerV)
 {
+  if (theDerU == 0 && theDerV == 0)
+  {
+    throw Standard_RangeError("Geom_RevolutionUtils::DN: (0,0) is not a derivative");
+  }
   const double aSin = std::sin(theU);
   const double aCos = std::cos(theU);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
template <typename CurveType>
inline gp_Vec DN(const double theU,
const double theV,
const CurveType& theBasis,
const gp_XYZ& theLoc,
const gp_XYZ& theAxis,
const int theDerU,
const int theDerV)
{
const double aSin = std::sin(theU);
const double aCos = std::cos(theU);
gp_XYZ aDV;
gp_XYZ aPntXYZ; // Store original point to avoid redundant curve evaluation
if (theDerV == 0)
{
gp_Pnt aP;
theBasis.D0(theV, aP);
aPntXYZ = aP.XYZ();
aDV = aPntXYZ - theLoc;
}
else
{
aDV = theBasis.DN(theV, theDerV).XYZ();
}
gp_XYZ aResult;
if (theDerU == 0)
{
// Just rotate the curve derivative
RotatePoint(aSin, aCos, gp_XYZ(0, 0, 0), theAxis, aDV, aResult);
}
else
{
// Compute shift and cross for the V-derivative vector
gp_XYZ aShift;
if (theDerV == 0)
{
ShiftPoint(theLoc, theAxis, aPntXYZ, aShift);
}
else
{
ShiftPoint(gp_XYZ(0, 0, 0), theAxis, aDV, aShift);
}
gp_XYZ aCross = theAxis.Crossed(aShift);
// Apply U-derivative pattern (periodic with period 4)
switch (theDerU % 4)
{
case 1: // -sin*shift + cos*cross
aResult.SetLinearForm(-aSin, aShift, aCos, aCross);
break;
case 2: // -cos*shift - sin*cross
aResult.SetLinearForm(-aCos, aShift, -aSin, aCross);
break;
case 3: // sin*shift - cos*cross
aResult.SetLinearForm(aSin, aShift, -aCos, aCross);
break;
case 0: // cos*shift + sin*cross
aResult.SetLinearForm(aCos, aShift, aSin, aCross);
break;
}
}
return gp_Vec(aResult);
}
template <typename CurveType>
inline gp_Vec DN(const double theU,
const double theV,
const CurveType& theBasis,
const gp_XYZ& theLoc,
const gp_XYZ& theAxis,
const int theDerU,
const int theDerV)
{
if (theDerU == 0 && theDerV == 0)
{
throw Standard_RangeError("Geom_RevolutionUtils::DN: (0,0) is not a derivative");
}
const double aSin = std::sin(theU);
const double aCos = std::cos(theU);
gp_XYZ aDV;
gp_XYZ aPntXYZ; // Store original point to avoid redundant curve evaluation
if (theDerV == 0)
{
gp_Pnt aP;
theBasis.D0(theV, aP);
aPntXYZ = aP.XYZ();
aDV = aPntXYZ - theLoc;
}
else
{
aDV = theBasis.DN(theV, theDerV).XYZ();
}
gp_XYZ aResult;
if (theDerU == 0)
{
// Just rotate the curve derivative
RotatePoint(aSin, aCos, gp_XYZ(0, 0, 0), theAxis, aDV, aResult);
}
else
{
// Compute shift and cross for the V-derivative vector
gp_XYZ aShift;
if (theDerV == 0)
{
ShiftPoint(theLoc, theAxis, aPntXYZ, aShift);
}
else
{
ShiftPoint(gp_XYZ(0, 0, 0), theAxis, aDV, aShift);
}
gp_XYZ aCross = theAxis.Crossed(aShift);
// Apply U-derivative pattern (periodic with period 4)
switch (theDerU % 4)
{
case 1: // -sin*shift + cos*cross
aResult.SetLinearForm(-aSin, aShift, aCos, aCross);
break;
case 2: // -cos*shift - sin*cross
aResult.SetLinearForm(-aCos, aShift, -aSin, aCross);
break;
case 3: // sin*shift - cos*cross
aResult.SetLinearForm(aSin, aShift, -aCos, aCross);
break;
case 0: // cos*shift + sin*cross
aResult.SetLinearForm(aCos, aShift, aSin, aCross);
break;
}
}
return gp_Vec(aResult);
}

Comment on lines +189 to 196
Vec Geom_SurfaceOfLinearExtrusion::DN(const Standard_Real U,
const Standard_Real,
const Standard_Integer Nu,
const Standard_Integer Nv) const
{
return myEvaluator->DN(U, V, Nu, Nv);
Standard_RangeError_Raise_if(Nu + Nv < 1 || Nu < 0 || Nv < 0, " ");
return Geom_ExtrusionUtils::DN(U, *basisCurve, direction.XYZ(), Nu, Nv);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Once we locate the header, find the declaration of DN
rg -n 'DN\s*\(' src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.hxx -A3

Repository: dpasukhi/OCCT

Length of output: 315


🏁 Script executed:

# Search for overrides of DN in derived classes
rg -n --glob='**/*.{cxx,hxx}' 'override.*DN\|DN.*override' -B2 -A3

Repository: dpasukhi/OCCT

Length of output: 39


🏁 Script executed:

# Search for any class that might inherit from Geom_SurfaceOfLinearExtrusion
rg -n 'Geom_SurfaceOfLinearExtrusion' --glob='**/*.{cxx,hxx}' -B1 -A1

Repository: dpasukhi/OCCT

Length of output: 50369


🏁 Script executed:

# Search for callers of DN method on Geom_SurfaceOfLinearExtrusion instances
rg -n '\.DN\s*\(' --glob='**/*.{cxx,hxx}' -B2 -A2 | head -50

Repository: dpasukhi/OCCT

Length of output: 3872


🏁 Script executed:

# Also check the base Geom_Surface class
rg -n 'DN\s*\(' src/ModelingData/TKG3d/Geom/Geom_Surface.hxx -A3

Repository: dpasukhi/OCCT

Length of output: 333


DN method: 2nd parameter is unnamed in implementation but named "V" in header and parent class.

The implementation at lines 189-196 has an unnamed 2nd parameter (const Standard_Real,), while the header declaration and parent class Geom_Surface::DN both have it explicitly named (const Standard_Real V). For a virtual method override, the signature must match exactly across header and implementation.

🤖 Prompt for AI Agents
In src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.cxx around lines
189-196, the DN implementation's second parameter is unnamed while the header
and base class declare it as "V"; update the function signature to name the
parameter (e.g., change "const Standard_Real," to "const Standard_Real V,") so
the override exactly matches the header/base declaration and rebuilds without
signature mismatch or unused-parameter warnings; keep the rest of the
implementation unchanged.

Comment on lines 93 to 98
void GeomAdaptor_SurfaceOfRevolution::Load(const Handle(Adaptor3d_Curve)& C)
{
myBasisCurve = C;
myBasisCurve = Handle(GeomAdaptor_Curve)::DownCast(C);
if (myHaveAxis)
Load(myAxis); // to evaluate the new myAxeRev.
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing null check after DownCast may cause issues.

The DownCast at line 95 will return a null handle if C is not a GeomAdaptor_Curve. If myBasisCurve becomes null, subsequent operations in Load(myAxis) at line 97 (e.g., myBasisCurve->GetType() at line 122) will cause a null pointer dereference.

Consider adding validation or documenting that only GeomAdaptor_Curve inputs are accepted.

 void GeomAdaptor_SurfaceOfRevolution::Load(const Handle(Adaptor3d_Curve)& C)
 {
   myBasisCurve = Handle(GeomAdaptor_Curve)::DownCast(C);
+  if (myBasisCurve.IsNull())
+  {
+    throw Standard_TypeMismatch("GeomAdaptor_SurfaceOfRevolution::Load - requires GeomAdaptor_Curve");
+  }
   if (myHaveAxis)
     Load(myAxis); // to evaluate the new myAxeRev.
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void GeomAdaptor_SurfaceOfRevolution::Load(const Handle(Adaptor3d_Curve)& C)
{
myBasisCurve = C;
myBasisCurve = Handle(GeomAdaptor_Curve)::DownCast(C);
if (myHaveAxis)
Load(myAxis); // to evaluate the new myAxeRev.
}
void GeomAdaptor_SurfaceOfRevolution::Load(const Handle(Adaptor3d_Curve)& C)
{
myBasisCurve = Handle(GeomAdaptor_Curve)::DownCast(C);
if (myBasisCurve.IsNull())
{
throw Standard_TypeMismatch("GeomAdaptor_SurfaceOfRevolution::Load - requires GeomAdaptor_Curve");
}
if (myHaveAxis)
Load(myAxis); // to evaluate the new myAxeRev.
}
🤖 Prompt for AI Agents
In src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_SurfaceOfRevolution.cxx around
lines 93-98, the result of Handle(GeomAdaptor_Curve)::DownCast(C) must be
null-checked before use; add a check immediately after the DownCast and handle
the null case (e.g., return early, throw a meaningful exception, or log and
assert) so that Load(myAxis) and later calls (like myBasisCurve->GetType())
never dereference a null handle; ensure the chosen behavior is consistent with
surrounding code (propagate the error or document and enforce the accepted input
type).

…utionUtils

- Updated EvaluateDN function in Geom_OffsetCurveUtils to support derivatives greater than 3, returning the basis curve derivative directly for improved accuracy.
- Refactored D0, D1, D2, and D3 methods in Geom_RevolutionUtils to utilize gp_Trsf for rotation transformations, enhancing clarity and maintainability.
- Simplified derivative calculations by removing redundant code and improving the handling of rotation axes, ensuring consistent evaluations across methods.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants