Files
2024-12-12 09:51:40 +01:00

614 lines
21 KiB
C#

//
// (C) Copyright 2003-2008 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Autodesk.Revit;
using Autodesk.Revit.Elements;
using Autodesk.Revit.Parameters;
using Autodesk.Revit.Geometry;
using CreApp = Autodesk.Revit.Creation.Application;
using Element = Autodesk.Revit.Element;
using GElement = Autodesk.Revit.Geometry.Element;
namespace Revit.SDK.Samples.FamilyExplorer.CS
{
/// <summary>
/// represents wire frame of the family
/// </summary>
public class FamilyWireFrame
{
/// <summary>
/// wrappers of family components
/// </summary>
private List<ComponentWireFrame> m_components;
/// <summary>
/// wrappers of family others
/// </summary>
private List<ComponentWireFrame> m_others;
/// <summary>
/// wrappers of family solid forms
/// </summary>
private List<ComponentWireFrame> m_solidForms;
/// <summary>
/// wrappers of family void forms
/// </summary>
private List<ComponentWireFrame> m_voidForms;
/// <summary>
/// The Application Creation object is used to create new instances of utility objects.
/// </summary>
private CreApp m_creApp;
private Family m_family; // the family to reprent.
private BoundingBoxXYZ m_bBox; // the bounding box of the family
private XYZ m_origin; // the origin point of the family.
private XYZ m_upDirection; // the up direction of the family.
private XYZ m_rightDirection; // the right direction of the family.
private XYZ m_frontDirection; // the front direction of the family.
private bool m_isInitialized; // the flag whether the profile is initialized.
/// <summary>
/// Family name to display.
/// </summary>
public string Name
{
get
{
return m_family.Name;
}
}
/// <summary>
/// the parameters of this family
/// </summary>
public string Parameters
{
get
{
string message = null;
foreach (Parameter para in m_family.Parameters)
{
message += para.Definition.Name + " : " + ParseParameter(para) + "\r\n";
}
return message;
}
}
/// <summary>
/// the bounding box of the family
/// </summary>
public BoundingBoxXYZ BoundingBox
{
get
{
return m_bBox;
}
set
{
m_bBox = value;
}
}
/// <summary>
/// the origin point of the family.
/// </summary>
public XYZ Origin
{
get
{
return m_origin;
}
set
{
m_origin = value;
}
}
/// <summary>
/// Whether the family has profile to preview.
/// </summary>
public bool IsEmpty
{
get
{
return (0 == m_components.Count
&& 0 == m_others.Count
&& 0 == m_solidForms.Count
&& 0 == m_voidForms.Count) ? true : false;
}
}
/// <summary>
/// For Internal Use Only.
/// </summary>
private FamilyWireFrame()
{
}
/// <summary>
/// default constructor
/// </summary>
/// <param name="family">the family to show profile</param>
/// <param name="creApp">The Application Creation object is
/// used to create new instances of utility objects. </param>
public FamilyWireFrame(Family family, CreApp creApp)
{
if (null == family)
{
throw new ArgumentNullException("family");
}
else
{
m_family = family;
}
if (null == creApp)
{
throw new ArgumentNullException("creApp");
}
else
{
m_creApp = creApp;
}
}
/// <summary>
/// Initialize the element geometry for object ComponetShow.
/// </summary>
public void InitilizeProfile()
{
//initialize an invalid bounding box
m_bBox = new BoundingBoxXYZ();
m_bBox.Max = new XYZ(double.MinValue, double.MinValue, double.MinValue);
m_bBox.Min = new XYZ(double.MaxValue, double.MaxValue, double.MaxValue);
//initialize all components of the family
m_components = new List<ComponentWireFrame>();
foreach (Element element in m_family.Components)
{
if (null == element)
{
continue;
}
ComponentWireFrame cs = new ComponentWireFrame(element, m_creApp, Brushes.Black, this);
if (!cs.IsEmpty)
{
m_components.Add(cs);
}
}
//initialize all others of the family
m_others = new List<ComponentWireFrame>();
foreach (Element element in m_family.Others)
{
if (null == element)
{
continue;
}
ComponentWireFrame cs = new ComponentWireFrame(element, m_creApp, Brushes.Gray, this);
if (!cs.IsEmpty)
{
m_others.Add(cs);
}
}
//initialize all solid forms of the family
m_solidForms = new List<ComponentWireFrame>();
foreach (GenericForm gf in m_family.SolidForms)
{
if (null == gf)
{
continue;
}
ComponentWireFrame cs = new ComponentWireFrame(gf, m_creApp, Brushes.Green, this);
if (!cs.IsEmpty)
{
m_solidForms.Add(cs);
}
}
//initialize all void forms of the family
m_voidForms = new List<ComponentWireFrame>();
foreach (GenericForm gf in m_family.VoidForms)
{
if (null == gf)
{
continue;
}
ComponentWireFrame cs = new ComponentWireFrame(gf, m_creApp, Brushes.Yellow, this);
if (!cs.IsEmpty)
{
m_voidForms.Add(cs);
}
}
//initialize the origin of this family.
m_origin = new XYZ((m_bBox.Max.X + m_bBox.Min.X) / 2,
(m_bBox.Max.Y + m_bBox.Min.Y) / 2,
(m_bBox.Max.Z + m_bBox.Min.Z) / 2);
//initialize the family orientation
m_upDirection = new XYZ(0, 0, 1);
m_rightDirection = new XYZ(1, 0, 0);
m_frontDirection = new XYZ(0, 1, 0);
// a flag show this object is initialized.
m_isInitialized = true;
}
/// <summary>
/// auto fit the family profile to preview.
/// </summary>
/// <param name="graphics"></param>
/// <param name="width"></param>
/// <param name="height"></param>
public void AutoFit(double width, double height)
{
if (!m_isInitialized)
{
InitilizeProfile();
}
if (!this.IsEmpty)// rotate this family to appropriate orientation
{
XYZ origin = m_origin;
XYZ axis = new XYZ(1, 0, -1);
double angle = Math.PI / 4;
//rotate the all components of this family
foreach (ComponentWireFrame cs in m_components)
{
cs.Rotate(origin, axis, angle);
}
//rotate the all others of this family
foreach (ComponentWireFrame cs in m_others)
{
cs.Rotate(origin, axis, angle);
}
//rotate the all solid forms of this family
foreach (ComponentWireFrame cs in m_solidForms)
{
cs.Rotate(origin, axis, angle);
}
//rotate the all void forms of this family
foreach (ComponentWireFrame cs in m_voidForms)
{
cs.Rotate(origin, axis, angle);
}
// rotate the bounding box.
XYZ max = m_bBox.Max;
XYZ min = m_bBox.Min;
Transform rotate = Transform.get_Rotation(origin, axis, angle);
m_bBox.Max = rotate.OfPoint(max);
m_bBox.Min = rotate.OfPoint(min);
// rotate the orientation
m_upDirection = rotate.OfVector(m_upDirection).Normalized;
m_rightDirection = rotate.OfVector(m_rightDirection).Normalized;
m_frontDirection = rotate.OfVector(m_frontDirection).Normalized;
// zoom the family to fit the screen
double elementWidth = Math.Abs(m_bBox.Max.X - m_bBox.Min.X);
double elementHeight = Math.Abs(m_bBox.Max.Y - m_bBox.Min.Y);
if (0 == elementWidth || 0 == elementHeight)
{
elementWidth = width / 2;
elementHeight = height / 2;
}
double xScale = Math.Abs((width / elementWidth));
double yScale = Math.Abs((height / elementHeight));
double scale = xScale < yScale ? xScale : yScale;
scale = scale / 2;
// zoom the all components of this family
foreach (ComponentWireFrame cs in m_components)
{
cs.Zoom(scale);
}
// zoom the all others of this family
foreach (ComponentWireFrame cs in m_others)
{
cs.Zoom(scale);
}
// zoom the all solid forms of this family
foreach (ComponentWireFrame cs in m_solidForms)
{
cs.Zoom(scale);
}
// zoom the all void forms of this family
foreach (ComponentWireFrame cs in m_voidForms)
{
cs.Zoom(scale);
}
// zoom the bounding box
XYZ distance = new XYZ((m_bBox.Max.X - m_origin.X) * scale
, (m_bBox.Max.Y - m_origin.Y) * scale
, (m_bBox.Max.Z - m_origin.Z) * scale);
Transform trf = Transform.get_Translation(distance);
origin = m_origin;
m_bBox.Max = trf.OfPoint(origin);
distance = new XYZ((m_bBox.Min.X - m_origin.X) * scale
, (m_bBox.Min.Y - m_origin.Y) * scale
, (m_bBox.Min.Z - m_origin.Z) * scale);
trf = Transform.get_Translation(distance);
m_bBox.Min = trf.OfPoint(origin);
//translate the family profile to fit the screen
XYZ move = new XYZ(width / 2 - m_origin.X, height / 2 - m_origin.Y, 0);
foreach (ComponentWireFrame cs in m_components)
{
cs.Translate(move.X, move.Y, move.Z);
}
foreach (ComponentWireFrame cs in m_others)
{
cs.Translate(move.X, move.Y, move.Z);
}
foreach (ComponentWireFrame cs in m_solidForms)
{
cs.Translate(move.X, move.Y, move.Z);
}
foreach (ComponentWireFrame cs in m_voidForms)
{
cs.Translate(move.X, move.Y, move.Z);
}
// translate the bounding box.
trf = Transform.get_Translation(move);
max = m_bBox.Max;
m_bBox.Max = trf.OfPoint(max);
min = m_bBox.Min;
m_bBox.Min = trf.OfPoint(min);
m_origin = trf.OfPoint(m_origin);
// translate the orientation
m_upDirection = trf.OfVector(m_upDirection).Normalized;
m_rightDirection = trf.OfVector(m_rightDirection).Normalized;
m_frontDirection = trf.OfVector(m_frontDirection).Normalized;
}
}
/// <summary>
/// rotate the family profile
/// </summary>
/// <param name="graphics">Encapsulates a GDI+ drawing surface.</param>
/// <param name="rotateAxis">the mode of rotate</param>
/// <param name="angle">the angle to rotate</param>
/// <returns>how many points rotated</returns>
public int Rotate(int rotateAxisMode, double angle)
{
int num = 0;
XYZ origin = m_origin;
XYZ axis = new XYZ(0, 1, 0);
switch (rotateAxisMode)
{
case 0:
axis = m_upDirection;
break;
case 1:
axis = m_rightDirection;
break;
case 2:
axis = m_frontDirection;
break;
default:
throw new ArgumentOutOfRangeException("rotateAxis");
}
foreach (ComponentWireFrame cs in m_components)
{
cs.Rotate(origin, axis, angle);
}
foreach (ComponentWireFrame cs in m_others)
{
cs.Rotate(origin, axis, angle);
}
foreach (ComponentWireFrame cs in m_solidForms)
{
cs.Rotate(origin, axis, angle);
}
foreach (ComponentWireFrame cs in m_voidForms)
{
cs.Rotate(origin, axis, angle);
}
//rotate the bounding box
XYZ max = m_bBox.Max;
XYZ min = m_bBox.Min;
Transform rotate = Transform.get_Rotation(origin, axis, angle);
m_bBox.Max = rotate.OfPoint(max);
m_bBox.Min = rotate.OfPoint(min);
//rotate the orientation
m_upDirection = rotate.OfVector(m_upDirection).Normalized;
m_rightDirection = rotate.OfVector(m_rightDirection).Normalized;
m_frontDirection = rotate.OfVector(m_frontDirection).Normalized;
return num;
}
/// <summary>
/// zoom the family profile
/// </summary>
/// <param name="graphics">Encapsulates a GDI+ drawing surface.</param>
/// <param name="scale">how much to scale</param>
/// <returns>how many points scaled</returns>
public int Zoom(double scale)
{
int num = 0;
foreach (ComponentWireFrame cs in m_components)
{
cs.Zoom(scale);
}
foreach (ComponentWireFrame cs in m_others)
{
cs.Zoom(scale);
}
foreach (ComponentWireFrame cs in m_solidForms)
{
cs.Zoom(scale);
}
foreach (ComponentWireFrame cs in m_voidForms)
{
cs.Zoom(scale);
}
// zoom the bounding box
XYZ distance = new XYZ((m_bBox.Max.X - m_origin.X) * scale
, (m_bBox.Max.Y - m_origin.Y) * scale
, (m_bBox.Max.Z - m_origin.Z) * scale);
Transform trf = Transform.get_Translation(distance);
XYZ origin = m_origin;
m_bBox.Max = trf.OfPoint(origin);
distance = new XYZ((m_bBox.Min.X - m_origin.X) * scale
, (m_bBox.Min.Y - m_origin.Y) * scale
, (m_bBox.Min.Z - m_origin.Z) * scale);
trf = Transform.get_Translation(distance);
m_bBox.Min = trf.OfPoint(origin);
return num;
}
/// <summary>
/// translate the family profile
/// </summary>
/// <param name="graphics">Encapsulates a GDI+ drawing surface.</param>
/// <param name="move">how much to translate</param>
/// <returns></returns>
public int Translate(XYZ move)
{
int num = 0;
foreach (ComponentWireFrame cs in m_components)
{
cs.Translate(move.X, move.Y, move.Z);
}
foreach (ComponentWireFrame cs in m_others)
{
cs.Translate(move.X, move.Y, move.Z);
}
foreach (ComponentWireFrame cs in m_solidForms)
{
cs.Translate(move.X, move.Y, move.Z);
}
foreach (ComponentWireFrame cs in m_voidForms)
{
cs.Translate(move.X, move.Y, move.Z);
}
// translate the bounding box
Transform trf = Transform.get_Translation(move);
XYZ max = m_bBox.Max;
m_bBox.Max = trf.OfPoint(max);
XYZ min = m_bBox.Min;
m_bBox.Min = trf.OfPoint(min);
m_origin = trf.OfPoint(m_origin);
// translate the orientation
m_upDirection = trf.OfVector(m_upDirection).Normalized;
m_rightDirection = trf.OfVector(m_rightDirection).Normalized;
m_frontDirection = trf.OfVector(m_frontDirection).Normalized;
return num;
}
public bool Draw(Graphics graphics)
{
if (this.IsEmpty)
{
return false;
}
foreach (ComponentWireFrame cs in m_components)
{
cs.RawDraw(graphics);
}
foreach (ComponentWireFrame cs in m_others)
{
cs.RawDraw(graphics);
}
foreach (ComponentWireFrame cs in m_solidForms)
{
cs.RawDraw(graphics);
}
foreach (ComponentWireFrame cs in m_voidForms)
{
cs.RawDraw(graphics);
}
return true;
}
/// <summary>
/// update the family bounding box
/// </summary>
/// <param name="point"></param>
public void UpdateBoundingBox(XYZ point)
{
XYZ max = new XYZ(m_bBox.Max.X, m_bBox.Max.Y, m_bBox.Max.Z);
max.X = max.X > point.X ? max.X : point.X;
max.Y = max.Y > point.Y ? max.Y : point.Y;
max.Z = max.Z > point.Z ? max.Z : point.Z;
m_bBox.Max = max;
XYZ min = new XYZ(m_bBox.Min.X, m_bBox.Min.Y, m_bBox.Min.Z);
min.X = min.X < point.X ? min.X : point.X;
min.Y = min.Y < point.Y ? min.Y : point.Y;
min.Z = min.Z < point.Z ? min.Z : point.Z;
m_bBox.Min = min;
}
/// <summary>
/// parse the parameter value to string
/// </summary>
/// <param name="parameter">the parameter to parse</param>
/// <returns>the parameter value string</returns>
private string ParseParameter(Parameter parameter)
{
switch (parameter.StorageType)
{
case StorageType.Double:
return parameter.AsDouble().ToString();
case StorageType.ElementId:
return parameter.AsElementId().Value.ToString();
case StorageType.Integer:
return parameter.AsInteger().ToString();
case StorageType.String:
return parameter.AsString();
default:
return null;
}
}
}
}