Hi @aignatovich . Your suggestion was the solution to my problem!. I took (if you don't mind) the liberty to extend the approach, so the method asks for the type name (string) of the dimension you want to assign:
private void CreateDimensions(
FilledRegion filledRegion,
XYZ dimensionDirection,
string typeName)
{
var document = filledRegion.Document;
var view = (View)document.GetElement(filledRegion.OwnerViewId);
var edgesDirection = dimensionDirection.CrossProduct(view.ViewDirection);
var edges = FindRegionEdges(filledRegion)
.Where(x => IsEdgeDirectionSatisfied(x, edgesDirection))
.ToList();
if (edges.Count < 2)
return;
// Se hace este ajuste para que la distancia no depende de la escala. <<<<<< evaluar para información de acotado y etiquetado!!!
var shift = UnitUtils.ConvertToInternalUnits(5 * view.Scale, DisplayUnitType.DUT_MILLIMETERS) * edgesDirection;
var dimensionLine = Line.CreateUnbound(
filledRegion.get_BoundingBox(view).Min + shift,
dimensionDirection);
var references = new ReferenceArray();
foreach (var edge in edges)
references.Append(edge.Reference);
Dimension dim = document.Create.NewDimension(view, dimensionLine, references);
ElementId dr_id = DimensionTypeId(
document, typeName);
if (dr_id != null)
{
dim.ChangeTypeId(dr_id);
}
}
private static bool IsEdgeDirectionSatisfied(Edge edge, XYZ edgeDirection)
{
var edgeCurve = edge.AsCurve() as Line;
if (edgeCurve == null)
return false;
return edgeCurve.Direction.CrossProduct(edgeDirection).IsAlmostEqualTo(XYZ.Zero);
}
private static IEnumerable<FilledRegion> FindFilledRegions(Document document, ElementId viewId)
{
var collector = new FilteredElementCollector(document, viewId);
return collector
.OfClass(typeof(FilledRegion))
.Cast<FilledRegion>();
}
private static IEnumerable<Edge> FindRegionEdges(FilledRegion filledRegion)
{
var view = (View)filledRegion.Document.GetElement(filledRegion.OwnerViewId);
var options = new Options
{
View = view,
ComputeReferences = true
};
return filledRegion
.get_Geometry(options)
.OfType<Solid>()
.SelectMany(x => x.Edges.Cast<Edge>());
}
private static ElementId DimensionTypeId(
Document doc,
string typeName)
{
List<Element> mt_coll = new FilteredElementCollector(doc)
.OfClass(typeof(DimensionType))
.WhereElementIsElementType()
.ToList();
DimensionType dimType = null;
foreach (Element type in mt_coll)
{
if (type is DimensionType)
{
if (type.Name == typeName)
{
dimType = type as DimensionType;
break;
}
}
}
return dimType.Id;
}
Hope this helps someone else!
Regards!