specklesystems / speckle-sharp

.NET SDK, Schema and Connectors: Revit, Rhino, Grasshopper, Dynamo, ETABS, AutoCAD, Civil3D & more.
https://speckle.systems
Apache License 2.0
363 stars 167 forks source link

Extend Pipe and Structure properties sent from C3D to facilitate mapping in other software (Revit) #3466

Closed alex-d-richards closed 2 months ago

alex-d-richards commented 3 months ago

What package are you referring to?

Civil 3d

Is your feature request related to a problem? Please describe.

We have been using Speckle to transfer data from C3D and recreating the model in Revit for coordination internally and externally.

Our intention is to be able to build a native representation in Revit using custom families, pipe systems etc. We found the properties exported by default from C3D a little limited and missing key information for this translation.

For example:

We have therefore been using dynamo as a workaround to push the additional properties from C3D to speckle although were finding some barriers to adoption and some pitfalls in the translation of the diaplayMesh.

However looking at the convertor for AutoCad Civil these additional properties can be added.

Describe the solution you'd like

Additional properties added to the base Native to Speckle conversion

Describe alternatives you've considered

Additional context

Default Properties Original Object Model

Additional Properties Additional Params

Related issues or community discussions

Alternative way around though Rvt -> C3d as opposed to C3d -> Rvt https://speckle.community/t/revit-family-civil-3d-pipe-network-structure/2928

alex-d-richards commented 3 months ago
public Structure StructureToSpeckle(CivilDB.Structure structure)
{
  // get ids pipes that are connected to this structure
  var pipeIds = new List<string>();
  var pipeNames = new List<string>();
  for (int i = 0; i < structure.ConnectedPipesCount; i++)
  {
    pipeIds.Add(structure.get_ConnectedPipe(i).ToString());

  }

  Structure speckleStructure = new()
  {
    location = PointToSpeckle(structure.Location, ModelUnits),
    pipeIds = pipeIds,
    displayValue = new List<Mesh>() { SolidToSpeckle(structure.Solid3dBody, out List<string> _) },
    units = ModelUnits,
    //applicationId = structure.Id.ToString()
  };

  // assign additional structure props
  AddNameAndDescriptionProperty(structure.Name, structure.Description, speckleStructure);

  try { speckleStructure["grate"] = structure.Grate; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["station"] = structure.Station; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["network"] = structure.NetworkName; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["sumpDepth"] = structure.SumpDepth; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["rimElevation"] = structure.RimElevation; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["sumpDepth"] = structure.SumpDepth; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["sumpElevation"] = structure.SumpElevation; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["wallThickness"] = structure.WallThickness; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["floorThickness"] = structure.FloorThickness; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["rotation"] = structure.Rotation; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["material"] = structure.Material; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["diameterOuter"] = structure.DiameterOrWidth; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["diameterInner"] = structure.InnerDiameterOrWidth; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["lengthOuter"] = structure.Length; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["lengthInner"] = structure.InnerLength; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["height"] = structure.Height; } catch (Exception e) when (!e.IsFatal()) { }
  try { speckleStructure["structureId"] = structure.Id.ToString(); } catch (Exception ex) when (!ex.IsFatal()) { }
  //try { speckleStructure["structureId"] = structure.Id; } catch (Exception ex) when (!ex.IsFatal()) { }

  return speckleStructure;
}
public Pipe PipeToSpeckle(CivilDB.Pipe pipe)
{
  // get the pipe curve
  ICurve curve;
  switch (pipe.SubEntityType)
  {
    case PipeSubEntityType.Straight:
      var line = new Acad.LineSegment3d(pipe.StartPoint, pipe.EndPoint);
      curve = LineToSpeckle(line);
      break;
    default:
      curve = CurveToSpeckle(pipe.BaseCurve);
      break;
  }

  Pipe specklePipe = new()
  {
    baseCurve = curve,
    diameter = pipe.InnerDiameterOrWidth,
    length = pipe.Length3DToInsideEdge,
    displayValue = new List<Mesh> { SolidToSpeckle(pipe.Solid3dBody, out List<string> notes) },
    units = ModelUnits,
    //applicationId = pipe.Id.ToString()
  };

  // assign additional pipe props
  AddNameAndDescriptionProperty(pipe.Name, pipe.Description, specklePipe);

  try { specklePipe["shape"] = pipe.CrossSectionalShape.ToString(); } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["slope"] = pipe.Slope; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["flowDirection"] = pipe.FlowDirection.ToString(); } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["flowRate"] = pipe.FlowRate; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["network"] = pipe.NetworkName; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["startOffset"] = pipe.StartOffset; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["endOffset"] = pipe.EndOffset; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["startStation"] = pipe.StartStation; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["endStation"] = pipe.EndStation; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["startStructure"] = pipe.StartStructureId.ToString(); } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["endStructure"] = pipe.EndStructureId.ToString(); } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["material"] = pipe.Material; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["thickness"] = pipe.WallThickness; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["slope"] = pipe.Slope; } catch (Exception ex) when (!ex.IsFatal()) { }
  try { specklePipe["pipeId"] = pipe.Id.ToString(); } catch (Exception ex) when (!ex.IsFatal()) { }
  //try { specklePipe["pipeId"] = pipe.Id; } catch (Exception ex) when (!ex.IsFatal()) { }

  return specklePipe;
}
clairekuang commented 3 months ago

Hey @alex-d-richards , could you take a look at this recent pr that adds PartData to pipes and structures? It does contain some of the missing properties you mentioned, but perhaps not all of them. Is the information in PartData enough, or do you require all of the properties?

alex-d-richards commented 3 months ago

hi @clairekuang thanks for reviewing this. I have pulled a copy the dev branch and from my limited testing so far this looks to provide the parameters that I was expecting.

Reviewing this same wok flow I do have a few other comments, queries but I think I will add these to the community page later in the week.