Rhino1RailSweep seems bugged

I’ve made some trivial tweaks to the cmdSampleSweep2 project to perform a Sweep1:

CRhinoCommand::result CCommandSampleSweep2::RunCommand(const CRhinoCommandContext& context)
{
// Select first rail curve
CRhinoGetObject go0;
go0.SetCommandPrompt(L"Select first rail");
go0.SetGeometryFilter(CRhinoGetObject::curve_object);
go0.EnablePreSelect(false);
go0.GetObjects(1, 1);
if (go0.CommandResult() != CRhinoCommand::success)
return go0.CommandResult();

const ON_Curve* rail0 = go0.Object(0).Curve();
if (nullptr == rail0)
return CRhinoCommand::failure;

// Select cross section curve
CRhinoGetObject gc;
gc.SetCommandPrompt(L"Select cross section");
gc.SetGeometryFilter(CRhinoGetObject::curve_object);
gc.EnablePreSelect(false);
gc.EnableDeselectAllBeforePostSelect(false);
gc.GetObjects(1, 1);
if (gc.CommandResult() != CRhinoCommand::success)
return gc.CommandResult();

const ON_Curve* crv = gc.Object(0).Curve();
if (nullptr == crv)
return CRhinoCommand::failure;

ON_SimpleArray<const ON_Curve*> shapes;
shapes.Append(crv);

bool bClosed = rail0->IsClosed();

// Make a 2-rail sweep
ON_SimpleArray<ON_Brep*> output_breps;
bool rc = Rhino1RailSweep(output_breps, rail0, shapes, bClosed, context.m_doc.AbsoluteTolerance());
if (rc)
{
for (int i = 0; i < output_breps.Count(); i++)
{
ON_Brep* brep = output_breps[i];
if (nullptr != brep)
{
CRhinoBrepObject* brep_obj = new CRhinoBrepObject();
brep_obj->SetBrep(brep);
brep = nullptr;
context.m_doc.AddObject(brep_obj);
}
}
context.m_doc.Redraw();
}

return CRhinoCommand::success;
}

The original Rhino2RailSweep worked as expected, and the stock Sweep1 command gives me a correct result, but Rhino1RailSweep gives me a disjointed output whenever it’s invoked on a polycurve (see bottom pic):

I’ve tried every other variant of the command with similar results (RhinoSweep1, RhinoSweep1Ex, Rhino1RailSweepSegmented etc.). Am I missing something?

1 Like

What happens if you first convert the polycurve to a nurbs curve?

Still getting a broken result after applying _ToNURBS and RebuildCrvNonUniform. It’s somehow even worse with open curves:

Hi @funkvessel,

Can you post your geometry?

Thanks,

– Dale

@dale Sorry for the delay, here’s the file:
test curve.3dm (21.0 KB)

Hi @funkvessel,

I’m confused - your model only contains a single closed curve. Sweep1 requires a single rail curve and one or more shape curves.

– Dale

Hi @dale, sorry, I should clarify: I omitted part of the code that generates a randomized NURBS profile curve for each rail curve in the document. Here’s a file with both curves present, and the code in its entirety:
test curve 2.3dm (21.3 KB)
cmdFNK_RandomRail.cpp (8.9 KB)

Hi @funkvessel,

Orienting the shape on the rail will produce better results.

sweep1.3dm (171.3 KB)

– Dale

@dale Did you perform the sweep using the SDK here? The initial orientation wasn’t ideal, but it still produces a valid sweep using Rhino’s sweep1 command. My concern is that the SDK commands produce an entirely incorrect result even when profiles are oriented correctly.

Hi @funkvessel,

I created the above with SampleCsSweep1.cs. But C++ works too.

CRhinoCommand::result CCommandTestSweep::RunCommand(
  const CRhinoCommandContext& context
)
{
  CRhinoGetObject get_rail;
  get_rail.SetCommandPrompt(L"Select rail curve");
  get_rail.SetGeometryFilter(CRhinoGetObject::curve_object);
  get_rail.EnableSubObjectSelect(false);
  get_rail.GetObjects(1, 1);
  if (get_rail.CommandResult() != CRhinoCommand::success)
    return get_rail.CommandResult();

  const CRhinoObjRef& rail_objref = get_rail.Object(0);
  const ON_Curve* rail_curve = rail_objref.Curve();
  if (nullptr == rail_curve)
    return CRhinoCommand::failure;

  CRhinoGetObject get_shape;
  get_shape.SetCommandPrompt(L"Select cross section curve");
  get_shape.SetGeometryFilter(CRhinoGetObject::curve_object);
  get_shape.EnableSubObjectSelect(false);
  get_shape.EnablePreSelect(false, false);
  get_shape.EnableDeselectAllBeforePostSelect(false);
  get_shape.GetObjects(1, 1);
  if (get_shape.CommandResult() != CRhinoCommand::success)
    return get_shape.CommandResult();

  const CRhinoObjRef& shape_objref = get_shape.Object(0);
  const ON_Curve* shape_curve = shape_objref.Curve();
  if (nullptr == shape_curve)
    return CRhinoCommand::failure;

  ON_SimpleArray<const ON_Curve*> shapes;
  shapes.Append(shape_curve);

  ON_SimpleArray<ON_Brep*> out_breps;
  double tolerance = context.m_doc.AbsoluteTolerance();

  Rhino1RailSweep(out_breps, rail_curve, shapes, false, tolerance);

  // A little post-process
  for (int i = 0; i < out_breps.Count(); i++)
  {
    if (out_breps[i])
    {
      out_breps[i]->SplitKinkyFaces();
      if (-1 == out_breps[i]->SolidOrientation())
        out_breps[i]->Flip();
    }

    CRhinoBrepObject* brep_obj = new CRhinoBrepObject();
    brep_obj->SetBrep(out_breps[i]);

    out_breps[i] = nullptr; // Now owned by brep_obj

    if (!context.m_doc.AddObject(brep_obj))
      delete brep_obj; // Don't leak...
  }

  context.m_doc.Redraw();

  return CRhinoCommand::success;
}

– Dale

1 Like