Reverse brep edge

Is there a way to reverse edge of a brep? I am trying to make a c# component that creates Sweep2 similar to what rhino does - keeping edges for continuity. So i am giving it brep and edge indices of that brep to not lose edges by converting them to curves.
But the problem is - i do not see any method for reversing edges (even though we have methods for splitting and joining edges). So my sweep comes out wrong.

Rhino sweep with continuity and no rebuild

GH Using edges:

GH Using reversed curve (appearently losing continuity)


using System;

using System.Collections.Generic;

using Rhino;

using Rhino.Geometry;




public class Script_Instance : GH_ScriptInstance

{

private void RunScript(

        Brep brep,

int rail1Index,

int rail2Index,

        List<int> shapeIndices,

int continuity,

bool maintainHeight,

bool closed,

ref object result,

ref object edgeCount)

  {

if (brep == null) { Print("No Brep."); return; }

int ec = brep.Edges.Count;

    edgeCount = ec;

if (rail1Index < 0 || rail1Index >= ec ||

        rail2Index < 0 || rail2Index >= ec)

    {

      Print($"Rail index out of range.");

return;

    }

if (shapeIndices == null || shapeIndices.Count == 0)

    {

      Print("Provide at least 1 index.");

return;

    }

    Curve rail1 = brep.Edges[rail1Index].DuplicateCurve();

    Curve rail2 = brep.Edges[rail2Index].DuplicateCurve();

var shapes = new List<Curve>();

foreach (int si in shapeIndices)

    {

if (si < 0 || si >= ec)

      {

        Print($"Shape index {si} out of range (0–{ec - 1}).");

return;

      }

      Curve shape = brep.Edges[si].DuplicateCurve();

double t;

      rail1.ClosestPoint(shape.PointAtStart, out t);

double dStartToRail1 = shape.PointAtStart.DistanceTo(rail1.PointAt(t));




      rail2.ClosestPoint(shape.PointAtStart, out t);

double dStartToRail2 = shape.PointAtStart.DistanceTo(rail2.PointAt(t));




if (dStartToRail2 < dStartToRail1)

        shape.Reverse();




if (continuity >= 1)

      {

        NurbsCurve nc = shape.ToNurbsCurve();

        nc.Rebuild(Math.Max(nc.Points.Count, 4), nc.Degree, false);

        shape = nc;

      }




      shapes.Add(shape);

    }

    {

      Curve s0 = shapes[0];

double tA, tB;

      rail1.ClosestPoint(s0.PointAtStart, out tA);

double dStart = s0.PointAtStart.DistanceTo(rail1.PointAt(tA));

double tNorm = (tA - rail1.Domain.Min) / rail1.Domain.Length;

if (tNorm > 0.5)

        rail1.Reverse();

    }

    {

      Curve s0 = shapes[0];

double tA;

      rail2.ClosestPoint(s0.PointAtEnd, out tA);

double tNorm = (tA - rail2.Domain.Min) / rail2.Domain.Length;

if (tNorm > 0.5)

        rail2.Reverse();

    }

var sweep = new SweepTwoRail();

    sweep.ClosedSweep           = closed;

    sweep.MaintainHeight        = maintainHeight;

    sweep.SweepTolerance        = RhinoMath.SqrtEpsilon;

    sweep.AngleToleranceRadians = RhinoMath.ToRadians(1.0);

    Brep[] results;




switch (continuity)

    {

case 2:

        results = sweep.PerformSweepRefit(rail1, rail2, shapes, RhinoMath.SqrtEpsilon);

break;

default:

        results = sweep.PerformSweep(rail1, rail2, shapes);

break;

    }

    result = results;

  }

}

missing

Do you think i am an idiot? Read my post again and think. CURVE and EDGE are different data types

Maybe this helps (if reverse UV direction is what you need). See Lunchbox

I think you might have to duplicate the edge to a curve.
Then flip the curve and try to re-construct the brep from this curve and the rest of the edges.

1 Like

Thanks maybe i will try that as well.. I tried duplicating and flipping brep, but it only reversed normals - did not change edge direction.

It sounds like a good idea, i will try that

Flipping the brep will only change the normal and I guess swich the uv-direction.

nevermind, it seems that i got the wrong idea in the first place. Sweep2 does not have inbuilt continuity matching, it uses
System.Boolean CreateFromMatch(BrepEdge edge, IEnumerable targetCurves, MatchSrfSettings settings, out Brep matched, out Brep target)

right after it. So it seems to be the way in gh too.

The functionality is very limited though.. Only matching one edge at a time. Here i loop through edges, losing continuity

This worked exactly as you described. Replacing edge helps, you solved it.
After replacing edge with flipped curve, it breaks brep - but edge is flipped successfully. So i just apply repair, and edge obtains reverse flag, and brep becomes valid.
I am leaving component here in case someone needs it

ReverseEdge.gh (27.6 KB)

edge.Reverse() does not do shit
ProxyCurveIsReversed is read only
BrepTrim.IsReversed is read only too.

Am I missing the point of what you are trying to do?

@Piotr This exists now natively in Grasshopper:

but it does not change the direction of the curve boundaries.

Hi Volker! Thank you for your take. No, that was not the task:) I was testing what surface creating components in api will change their outputs if you give them edge instead of curve as input. And for some components i needed to flip edge as you would flip curve, because they were producing incorrect results.

Because my work is often related with making parts with good continuity, i am trying to explore workflows that would allow me to create such parts in grasshopper. So far, I found NetworkSurface to be able to react with continuous results. For that i give it brep, and indices of edges i want to use for surface creation. Its the same in rhino - if you try to create network surface with edges and curves, you will see that chosing edges allows you to have continuity, while curves do not support that. Because edges are part of brep, and allow method’s solver to access information such as adjacent surface and its normals

You can see the difference between providing network surface edge and curve:

The second might not look the best, i made its 4th curve a line on purpose. But it is the key for creation of parts with continuity between surfaces. You can see that it reacts to surface normals

I would have assumed that Network Surface treats BRep edges just like any curve, using its perp frames to make the surface. I do know that you need to be careful about pushing curves through curve containers because you do not necessarily get the same curve back… or maybe this was just as I was pushing a curve through a line container and I got a different domain.

I can’t tell from the screen shots alone.

NetworkSrfEdge.gh (25.6 KB)


take a note, that both grasshopper component and c# component use same method. c# does not deconstruct brep or does anything with it. Only difference is that inside c# component we can use brep edge data type. Because as soon as you take edges out of brep into grasshopper, it becomes simple curve.

1 Like


and judging from this, we have edge data type in grasshopper, its just components do not support it yet

This is what I am talking about.

That happens because inputs to components have curve input data type. I would assume it casts edges to curves on the entrance to the component. Iater i will try to use eges by treating them as objects

Have you tried the new Continuous Patch component from the Rhino 9 WIP?

It has so many inputs, I wouldn’t know where to start.