Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Closed Sketch made of Arcs for Floor Creation

1 REPLY 1
SOLVED
Reply
Message 1 of 2
Anonymous
395 Views, 1 Reply

Closed Sketch made of Arcs for Floor Creation

Good day,

 

yesterday I had the issue to create a closed slabedge made of a series of arches or a combination of arches and straight lines. There are 3 ways to create an arc, but actually only one works for me as the double precission in revit kills you. The input comes from a database and the user can create an arc by:

 

  1. Start - End - Point on arc
  2. Center - Start - End

As I will only use method 1 as method 2 doesn't exist in the api, I wrote a function to convert method 2 in method 1.

 

public static XYZ GetMidPoint(XYZ sPoint, XYZ ePoint, XYZ cPoint)
{

XYZ sDir = sPoint - cPoint;
XYZ eDir = ePoint - cPoint;

double sR = Math.Sqrt(sDir.X * sDir.X + sDir.Y * sDir.Y + sDir.Z * sDir.Z); // Start radius
double eR = Math.Sqrt(eDir.X * eDir.X + eDir.Y * eDir.Y + eDir.Z * eDir.Z); // End radius
double mR = (sR + eR) / 2; // Radius of the midpoint

XYZ mDir = (eDir + sDir) / 2; // Director for the midpoint
// Norm of the midpoint director (used to normalize the director)
double norm_mDir = Math.Sqrt( mDir.X * mDir.X + mDir.Y * mDir.Y + mDir.Z * mDir.Z );
/*
if (eR == 0 || sR/eR < 0.9999 || sR/eR > 1.0001)
{
//MessageBox.Show("Three points do not make an arc.");
}
*/
XYZ mPoint = new XYZ(cPoint.X + mDir.X * mR / norm_mDir, cPoint.Y + mDir.Y * mR / norm_mDir, cPoint.Z + mDir.Z * mR / norm_mDir);
return mPoint;
}

 

For degugging I had a messagebox pop up just to see revits internal impressive precission ;-).

 

The code creating the floor plate that uses this function see below.

 

public static Floor PlaceSlab(Document uidoc, List<XYZ> CoordList, Level baseLevel, double thickness, double offset, List<ArcEntry> ThirdPoints)
{
FloorType aFloorType = null;
FloorType newFloorType = null;
bool FloorTypeExists = false;

string NewFloorTypeName = "Slab_" + (thickness * 1000).ToString();

FilteredElementCollector collector = new FilteredElementCollector(uidoc);
collector.OfClass(typeof(FloorType));

foreach (FloorType floortype in collector)
{
if (floortype.Name == NewFloorTypeName)
{
aFloorType = floortype;
FloorTypeExists = true;
break;
}
}

if (FloorTypeExists == false)
{
foreach (FloorType floortype in collector)
{
if (floortype.Name == "150 Concrete" || floortype.Name == "Generic 150mm")
{
aFloorType = floortype;
break;
}
}

newFloorType = aFloorType.Duplicate(NewFloorTypeName) as FloorType;

if (newFloorType != null)
{
CompoundStructure cs = newFloorType.GetCompoundStructure();

double layerWidth = UnitUtils.Convert(thickness, DisplayUnitType.DUT_METERS, DisplayUnitType.DUT_DECIMAL_FEET);
int layerIndex = cs.GetFirstCoreLayerIndex();

IList<CompoundStructureLayer> cslayers = cs.GetLayers();

foreach (CompoundStructureLayer csl in cslayers)
{
cs.SetLayerWidth(layerIndex, layerWidth);
layerIndex++;
}
newFloorType.SetCompoundStructure(cs);
}
}
else
{
newFloorType = aFloorType;
}

CurveArray SlabEdge = new CurveArray();
XYZ NormZ = new XYZ(0,0,1);
XYZ NormX = new XYZ(1,0,0);

for (int i = 0; i < CoordList.Count; i++)
{
if (ThirdPoints.Count > 0)
{
if (i == (CoordList.Count - 1))
{
// 0 - Line
// 1 - MidPoint Arc
// 2 - 3 Point Arc
switch (ThirdPoints[i].ArcType)
{
case 0:

Line aLine = Line.CreateBound(CoordList[i], CoordList[0]);
SlabEdge.Append(aLine);
break;

case 1:

try
{
XYZ mPoint = GlobalFunctions.GetMidPoint(CoordList[i], CoordList[0], ThirdPoints[i].CLine);
Arc aArc1 = Arc.Create(CoordList[i], CoordList[0], mPoint);
SlabEdge.Append(aArc1);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}

break;

case 2:
Arc aArc2 = Arc.Create(CoordList[i],CoordList[0],ThirdPoints[i].CLine);
SlabEdge.Append(aArc2);
break;
}
}
else
{
// 0 - Line
// 1 - MidPoint Arc
// 2 - 3 Point Arc
switch (ThirdPoints[i].ArcType)
{
case 0:

Line aLine = Line.CreateBound(CoordList[i], CoordList[i+1]);
SlabEdge.Append(aLine);
break;

case 1:
try
{
XYZ mPoint = GlobalFunctions.GetMidPoint(CoordList[i], CoordList[i + 1], ThirdPoints[i].CLine);
Arc aArc1 = Arc.Create(CoordList[i], CoordList[i + 1], mPoint);
SlabEdge.Append(aArc1);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
break;

case 2:
Arc aArc2 = Arc.Create(CoordList[i], CoordList[i + 1], ThirdPoints[i].CLine);
SlabEdge.Append(aArc2);
break;
}
}
}
else
{
if (i == (CoordList.Count - 1))
{
Line aLine = Line.CreateBound(CoordList[i], CoordList[0]);
SlabEdge.Append(aLine);
}
else
{
Line aLine = Line.CreateBound(CoordList[i], CoordList[i + 1]);
SlabEdge.Append(aLine);
}
}
}

// Create a slab using the location line and slab type
try
{
Floor newFloor = uidoc.Create.NewFloor(SlabEdge, newFloorType, baseLevel, true);
double offSet = UnitUtils.Convert(offset, DisplayUnitType.DUT_METERS, DisplayUnitType.DUT_DECIMAL_FEET);
newFloor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM).Set(offSet);

return newFloor;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return null;
}
}

 

Maybe this code will help someone as it took me some hours to get it to work and here a screenshot with the final slabs.

 

revit_slabs_arc_sketch.png

 

regards

Christian

1 REPLY 1
Message 2 of 2
mikako_harada
in reply to: Anonymous

Hi Christian, 

 

Excellent!  Thank you for sharing and thinking about the community!

 

(Update: Looks like we cannot accept the original post as a solution.  Allow me to check mark here so that others knows that original post includes solution.) 


Mikako Harada
Developer Technical Services

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


Rail Community