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: 

Create Mass From Room

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
grahamcook
4573 Views, 8 Replies

Create Mass From Room

Hi

I'm a bit out of my comfort zone here.  I am creating an addin which involves creating a mass for each instance of room.  I cobbled together the code below from examples on other blogs / sites (mostly here).  This works but only if the room hasn't got any internal boundaries (holes, islands, etc).  If a room has an internal boundary the actual NewExtrution line fails with the error "One of the conditions for the inputs was not satisfied. Consult the documentation for requirements for each argument.".  I'm guessing this is because the profile array has more than one profile (like internal boundaries in this case).  The boundaries don't overlap though, just some are entirely consumed by others.

 

Anyone know of a better approach here?  Or how to amend the code below to deal with the internal boundaries (holes) in the room?

 

// Create family doc from template
Autodesk.Revit.DB.Document familyDoc = app.NewFamilyDocument(@"C:\ProgramData\Autodesk\RVT 2013\Family Templates\English\Metric Generic Model.rft");

// Save the new Family - room is Room Element not defined in this sample code
string fileName = @"C:\Temp\" + room.UniqueId.ToString() + ".rfa";
familyDoc.SaveAs(fileName);

Transaction transaction = new Transaction(familyDoc, "RoomToMass");
transaction.Start();

// Get the room boundary
SpatialElementBoundaryOptions opt = new SpatialElementBoundaryOptions();

IList<IList<Autodesk.Revit.DB.BoundarySegment>> segArray = room.GetBoundarySegments(opt);

CurveArray curveArray = new CurveArray();

// Iterate to gather the curve objects
foreach (IList<Autodesk.Revit.DB.BoundarySegment> bSegments in segArray)
{
    foreach (Autodesk.Revit.DB.BoundarySegment bSegment in bSegments)
    {
        curveArray.Append(bSegment.Curve);
    }
}

// Origin point and normal point that gives the extrusion direction
XYZ ptOrigin = new XYZ(0, 0, 0);
XYZ ptNormal = new XYZ(0, 0, 1);

// The plane to extrude the mass from
Plane plane = app.Create.NewPlane(ptNormal, ptOrigin);
SketchPlane sketchPlane = familyDoc.FamilyCreate.NewSketchPlane(plane);

// Add the CurveArray to a CurveArrArray
CurveArrArray curveArrArray = new CurveArrArray();
curveArrArray.Append(curveArray);

// Extrude the form 10 feet as test
Extrusion extrusion = familyDoc.FamilyCreate.NewExtrusion(true, curveArrArray, sketchPlane, 10);

transaction.Commit();

familyDoc.Save();

// now need to place the family...

 

8 REPLIES 8
Message 2 of 9
saikat
in reply to: grahamcook

Hello Graham

 

Is it an option to create new model lines that outline the outer periphery/shell of the room using the room's boundary segments (instead of directly using the curves of the room boundary segments) and then use this set of curves in a curvearray to create the mass element.

 

cheers

 

 



Saikat Bhattacharya
Senior Manager - Technology Consulting
Message 3 of 9
grahamcook
in reply to: saikat

Saikat

 

Thanks for looking at my post.

Yes that would be an option i could look at.  If i knew how to just get the boundary of the OUTER edge only - ignoring all the inner boundaries.  Any Pointers?

 

Cheers

 

Graham

Message 4 of 9
saikat
in reply to: grahamcook

Hello Graham

 

Would an approach similar to what is being discussed here be of help/use:

http://thebuildingcoder.typepad.com/blog/2008/12/2d-polygon-areas-and-outer-loop.html

 

Do let us know if this worked out or not. Or if you found any other approach, better still.

 

cheers



Saikat Bhattacharya
Senior Manager - Technology Consulting
Message 5 of 9
grahamcook
in reply to: saikat

Thank you Saikat.  In this case i went with assuming the first segment set in the collection was the outer boundary and inserted a break in the first foreach loop to force a break after first loop.  I've tested on hundreds of rooms and the first segment set has always been the outer edge (so far).  I would like to eventually include holes within the mass but for this particular problem just the outer edge will suffice.

 

Cheers

 

Graham

Message 6 of 9
saikat
in reply to: grahamcook

Great! Thanks for the update.

 

kind regards



Saikat Bhattacharya
Senior Manager - Technology Consulting
Message 7 of 9
moses.scott
in reply to: grahamcook

I am trying to comile this code in Visual Studio Express 2013. 

I need to compile for Revit 2014

 

What is the Class that goes avove this code block?

 

// Origin point and normal point that gives the extrusion direction
XYZ ptOrigin = new XYZ(0, 0, 0);
XYZ ptNormal = new XYZ(0, 0, 1);


Message 8 of 9
moses.scott
in reply to: saikat

What are the classes I need to incorporate to make this code work for Revit 2014 addin

 

Also, can I compile this for Dynamo?

 

I think the code as pasted above is missing the following class:

 

public Extrusion NewExtrusion(
bool isSolid,
CurveArrArray profile,
SketchPlane sketchPlane,
double end
)

 

Tags (3)
Message 9 of 9
moses.scott
in reply to: grahamcook

I believe this Code will retrieve the flat extrusion of a room object.

 

Sometimes rooms are cut off by pitched roofs.

 

If Get Geometry is used from the API, can the Room Solids be simply be put into a mass family?

 

See below example of beam.get_Geometry(options)

 

 

Is it possible to use rooms.get_Geometry(options):

 

 

 

 

 

 

public void GetCurvesFromABeam(Autodesk.Revit.DB.FamilyInstance beam,
                               Autodesk.Revit.DB.Options options)
{
    Autodesk.Revit.DB.GeometryElement geomElem = beam.get_Geometry(options);

    Autodesk.Revit.DB.CurveArray curves = new CurveArray();
    Autodesk.Revit.DB.SolidArray solids = new SolidArray();

    //Find all solids and insert them into solid array
    AddCurvesAndSolids(geomElem, ref curves, ref solids);
}

private void AddCurvesAndSolids(Autodesk.Revit.DB.GeometryElement geomElem,
                                ref Autodesk.Revit.DB.CurveArray curves,
                                ref Autodesk.Revit.DB.SolidArray solids)
{
    foreach (Autodesk.Revit.DB.GeometryObject geomObj in geomElem)
    {
        Autodesk.Revit.DB.Curve curve = geomObj as Autodesk.Revit.DB.Curve;
        if (null != curve)
        {
            curves.Append(curve);
            continue;
        }
        Autodesk.Revit.DB.Solid solid = geomObj as Autodesk.Revit.DB.Solid;
        if (null != solid)
        {
            solids.Append(solid);
            continue;
        }
        //If this GeometryObject is Instance, call AddCurvesAndSolids
        Autodesk.Revit.DB.GeometryInstance geomInst = geomObj as Autodesk.Revit.DB.GeometryInstance;
        if (null != geomInst)
        {
            Autodesk.Revit.DB.GeometryElement transformedGeomElem
              = geomInst.GetInstanceGeometry(geomInst.Transform);
            AddCurvesAndSolids(transformedGeomElem, ref curves, ref solids);
        }
    }
}

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community