mirror of
https://github.com/jeremytammik/RevitSdkSamples.git
synced 2026-09-19 18:48:48 +00:00
added Revit 2022 SDK minus except *rvt and *rfa
This commit is contained in:
@@ -0,0 +1,335 @@
|
||||
//
|
||||
// (C) Copyright 2003-2019 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.Xml.Linq;
|
||||
using System.Linq;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.PointClouds;
|
||||
using Autodesk.Revit.UI;
|
||||
|
||||
|
||||
|
||||
namespace Revit.SDK.Samples.CS.PointCloudEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class for all IPointCloudAccess implementations in this sample.
|
||||
/// </summary>
|
||||
public class PointCloudAccessBase
|
||||
{
|
||||
#region Class Member Variables
|
||||
private double m_scale = 1.0;
|
||||
private List<PointCloudCellStorage> m_storedCells;
|
||||
private Outline m_outline = null;
|
||||
#endregion
|
||||
|
||||
#region Class Methods
|
||||
/// <summary>
|
||||
/// Constructs a new instance of the base class.
|
||||
/// </summary>
|
||||
protected PointCloudAccessBase()
|
||||
{
|
||||
m_storedCells = new List<PointCloudCellStorage>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new cell to the point cloud.
|
||||
/// </summary>
|
||||
/// <param name="lowerLeft">The lower left point.</param>
|
||||
/// <param name="upperRight">The upper right point.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="randomize">True to randomize point number and location, false for a regular arrangement of points.</param>
|
||||
protected void AddCell(XYZ lowerLeft, XYZ upperRight, int color, bool randomize)
|
||||
{
|
||||
PointCloudCellStorage storage = new PointCloudCellStorage(lowerLeft, upperRight, color, randomize);
|
||||
storage.GeneratePoints();
|
||||
m_storedCells.Add(storage);
|
||||
|
||||
AddCellToOutline(storage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new cell to the point cloud.
|
||||
/// </summary>
|
||||
/// <param name="lowerLeft">The lower left point.</param>
|
||||
/// <param name="upperRight">The upper right point.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
protected void AddCell(XYZ lowerLeft, XYZ upperRight, int color)
|
||||
{
|
||||
AddCell(lowerLeft, upperRight, color, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a cell to the stored outline of the point cloud. If the cell boundaries extend beyond the current outline, the outline
|
||||
/// is adjusted.
|
||||
/// </summary>
|
||||
/// <param name="storage"></param>
|
||||
private void AddCellToOutline(PointCloudCellStorage storage)
|
||||
{
|
||||
XYZ lowerLeft = storage.LowerLeft;
|
||||
XYZ upperRight = storage.UpperRight;
|
||||
if (m_outline == null)
|
||||
m_outline = new Outline(lowerLeft, upperRight);
|
||||
else
|
||||
{
|
||||
XYZ minimumPoint = m_outline.MinimumPoint;
|
||||
|
||||
m_outline.MinimumPoint = new XYZ(Math.Min(minimumPoint.X, lowerLeft.X),
|
||||
Math.Min(minimumPoint.Y, lowerLeft.Y),
|
||||
Math.Min(minimumPoint.Z, lowerLeft.Z));
|
||||
|
||||
XYZ maximumPoint = m_outline.MaximumPoint;
|
||||
m_outline.MaximumPoint = new XYZ(Math.Max(maximumPoint.X, upperRight.X),
|
||||
Math.Max(maximumPoint.Y, upperRight.Y),
|
||||
Math.Max(maximumPoint.Z, upperRight.Z));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the outline calculated from all cells in the point cloud.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected Outline GetOutline()
|
||||
{
|
||||
return m_outline;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale stored for this point cloud.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected double GetScale()
|
||||
{
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the contents of the point cloud into an XML element.
|
||||
/// </summary>
|
||||
/// <param name="rootElement">The XML element in which to save the point cloud properties.</param>
|
||||
public virtual void SerializeObjectData(XElement rootElement)
|
||||
{
|
||||
XElement scaleElement = XmlUtils.GetXElement(m_scale, "Scale");
|
||||
rootElement.Add(scaleElement);
|
||||
|
||||
int count = m_storedCells.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
XElement cellElement = new XElement("Cell");
|
||||
m_storedCells[i].SerializeObjectData(cellElement);
|
||||
rootElement.Add(cellElement);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The internal implementation for point cloud read requests from Revit.
|
||||
/// </summary>
|
||||
/// <remarks>Both IPointCloudAccess.ReadPoints() and IPointSetIterator.ReadPoints() are served by this method.</remarks>
|
||||
/// <param name="rFilter">The point cloud filter.</param>
|
||||
/// <param name="buffer">The point cloud buffer.</param>
|
||||
/// <param name="nBufferSize">The maximum number of points in the buffer.</param>
|
||||
/// <param name="startIndex">The start index for points. Pass 0 if called from IPointCloudAccess.ReadPoints() or if this is the first
|
||||
/// call to IPointSetIterator.ReadPoints(). Pass the previous cumulative number of read points for second and successive calls to
|
||||
/// IPointSetIterator.ReadPoints().</param>
|
||||
/// <returns>The number of points read.</returns>
|
||||
protected unsafe int ReadSomePoints(PointCloudFilter rFilter, IntPtr buffer, int nBufferSize, int startIndex)
|
||||
{
|
||||
// Get the pointer to the buffer.
|
||||
CloudPoint* cpBuffer = (CloudPoint*)buffer.ToPointer();
|
||||
int pointIndex = 0;
|
||||
int currentIndex = startIndex;
|
||||
int totalPoints = 0;
|
||||
int startCell = 0;
|
||||
Outline fullOutline = GetOutline();
|
||||
|
||||
// Test each cell until the first cell with needed points is found.
|
||||
for (int i = 0; i < m_storedCells.Count; i++)
|
||||
{
|
||||
PointCloudCellStorage cell = m_storedCells[i];
|
||||
|
||||
// Pass the cell outline to the filter.
|
||||
int filterResult = rFilter.TestCell(cell.LowerLeft, cell.UpperRight);
|
||||
|
||||
// Filter result == -1 means the cell is completely out of scope for the filter.
|
||||
if (filterResult == -1)
|
||||
continue;
|
||||
|
||||
// The cell is at least partially in scope. If the cell has more points than
|
||||
// the number read in previous calls, we should start with this cell.
|
||||
// If it has less points than the number read, the cell was already processed and we
|
||||
// should move to the next one.
|
||||
totalPoints += cell.NumberOfPoints;
|
||||
if (currentIndex < totalPoints)
|
||||
{
|
||||
startCell = i;
|
||||
currentIndex = Math.Max(0, startIndex - totalPoints);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Start with the current candidate cell and read cells until there are no more to read.
|
||||
for (int i = startCell; i < m_storedCells.Count; i++)
|
||||
{
|
||||
// Test the cell against the filter.
|
||||
PointCloudCellStorage cell = m_storedCells[i];
|
||||
int filterResult = rFilter.TestCell(cell.LowerLeft, cell.UpperRight);
|
||||
|
||||
// Filter result == -1 means the cell is entirely out of scope, skip it.
|
||||
if (filterResult == -1)
|
||||
continue;
|
||||
|
||||
// Filter result == 0 means some part of the cell is in scope.
|
||||
// Prepare for cell is called to process the cell's points.
|
||||
if (filterResult == 0)
|
||||
rFilter.PrepareForCell(fullOutline.MinimumPoint, fullOutline.MaximumPoint, cell.NumberOfPoints);
|
||||
|
||||
// Loop through all points in the cell.
|
||||
for (int j = currentIndex; j < cell.NumberOfPoints; j++)
|
||||
{
|
||||
// If we need to test the point for acceptance, use the filter to do so.
|
||||
// If filter result == 1 the entire cell was in scope, no need to test.
|
||||
if (filterResult == 0)
|
||||
{
|
||||
if (!rFilter.TestPoint(cell.PointsBuffer[j]))
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the point to the buffer and increment the counter
|
||||
*(cpBuffer + pointIndex) = cell.PointsBuffer[j];
|
||||
pointIndex++;
|
||||
|
||||
// Stop when the max number of points is reached
|
||||
if (pointIndex >= nBufferSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop when the max number of points is reached
|
||||
if (pointIndex >= nBufferSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
return pointIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up a point cloud from an XML root element.
|
||||
/// </summary>
|
||||
/// <param name="rootElement">The root element.</param>
|
||||
protected void SetupFrom(XElement rootElement)
|
||||
{
|
||||
// Read scale, if it exists.
|
||||
foreach (XElement scaleElement in rootElement.Elements("Scale"))
|
||||
{
|
||||
double scale = XmlUtils.GetDouble(scaleElement);
|
||||
if (scale < 0.0)
|
||||
{
|
||||
TaskDialog.Show("Scale error", "The value of scale is not a valid number greater than zero.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
// Read cells.
|
||||
m_storedCells = new List<PointCloudCellStorage>();
|
||||
foreach (XElement cellElement in rootElement.Elements("Cell"))
|
||||
{
|
||||
PointCloudCellStorage cell = new PointCloudCellStorage(cellElement);
|
||||
m_storedCells.Add(cell);
|
||||
AddCellToOutline(cell);
|
||||
cell.GeneratePoints();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// The implementation for an IPointSetIterator for a file-based or predefined point cloud.
|
||||
/// </summary>
|
||||
protected class PointCloudAccessBaseIterator : IPointSetIterator
|
||||
{
|
||||
#region Class Member Variables
|
||||
private PointCloudFilter m_filter;
|
||||
private int m_currentIndex;
|
||||
private PointCloudAccessBase m_access;
|
||||
private bool m_done = false;
|
||||
#endregion
|
||||
|
||||
#region Class Methods
|
||||
/// <summary>
|
||||
/// Constructs a new instance of the point cloud iterator.
|
||||
/// </summary>
|
||||
/// <param name="access">The access.</param>
|
||||
/// <param name="filter">The filter used for this iteration.</param>
|
||||
public PointCloudAccessBaseIterator(PointCloudAccessBase access, PointCloudFilter filter)
|
||||
{
|
||||
m_access = access;
|
||||
m_filter = filter;
|
||||
m_currentIndex = 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IPointSetIterator Members
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of IPointSetIterator.ReadPoints()
|
||||
/// </summary>
|
||||
/// <param name="buffer">The point buffer.</param>
|
||||
/// <param name="nBufferSize">The buffer size.</param>
|
||||
/// <returns>The number of points read.</returns>
|
||||
public int ReadPoints(IntPtr buffer, int nBufferSize)
|
||||
{
|
||||
if (m_done)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int found = m_access.ReadSomePoints(m_filter, buffer, nBufferSize, m_currentIndex);
|
||||
m_currentIndex += found;
|
||||
|
||||
if (found > nBufferSize)
|
||||
{
|
||||
m_done = true;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of IPointSetIterator.Free()
|
||||
/// </summary>
|
||||
public void Free()
|
||||
{
|
||||
m_done = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user