draw a pipe in autocad 3d
Past Augusto Goncalves
On the UI it's possible to select Pipes, erase the Tag (prepare as unassigned) then set information technology back. In some cases, this is a workflow to fix tag problems on Pipes, that tin reflect on ISO generation.
The idea of this code is: on the database level (DataLinksManager), get all the PipeRunComponents, Fasteners and P3dConnector, then finally Unrelate and Relate again. The purpose is to force Plant 3D to rebuild its structure and restore.
Thanks to Jorge Lopez (big) assist on this!
Important: if you program to use this, ensure you take a fill-in of your project.
[CommandMethod("tryFixPipeTag")]
publicstaticvoid CmdTryFixLineTag()
{
Editor ed = Application.DocumentManager.
MdiActiveDocument.Editor;PlantProject currentProj =
PlantApplication.CurrentProject;
PipingProject pipeProj =
(PipingProject)currentProj.ProjectParts["Pipage"];
DataLinksManager dlm =
pipeProj.DataLinksManager;PnPDatabase db = dlm.GetPnPDatabase();
db.StartTransaction();
int dwgRowId = dlm.GetDrawingId(
Awarding.DocumentManager.MdiActiveDocument.Database);
PnPRowIdArray groupIds = dlm.GetRelatedRowIds(
"P3dDrawingLineGroupRelationship", "Drawing",
dwgRowId, "LineGroup");foreach (int groupId in groupIds)
{
List<PnPRow> rowsToFix = newList<PnPRow>();
PnPRow rowLineGroup = db.GetRow(groupId);string tag = rowLineGroup["Tag"] equallystring;
if (string.IsNullOrWhiteSpace(tag)) continue;ed.WriteMessage("\n{0}", tag);
System.Diagnostics.Debug.WriteLine(
string.Format("\n{0}", tag));// Go pipe run components
//
PnPTable tblPipes = db.Tables["PipeRunComponent"];
PnPRow[] rowsPipes = tblPipes.Select(
string.Format("LineNumberTag='{0}'", tag));AddRowsToUniqueList(rowsToFix, rowsPipes);
// Go fasteners
//
PnPTable tblFastener = db.Tables["Fasteners"];
PnPRow[] rowsFastener = tblFastener.Select(
string.Format("LineNumberTag='{0}'", tag));AddRowsToUniqueList(rowsToFix, rowsFastener);
// Get P3dConnectors
//
PnPTable tblConnector = db.Tables["P3dConnector"];
// merely in example, make sure all rows are loaded in
tblConnector.Select();foreach (PnPRow rowFastener in rowsFastener)
{
PpObjectIdArray arr = dlm.FindAcPpObjectIds(rowFastener.RowId);
foreach (PpObjectId ppId in arr)
{
PpObjectId ppConnectorId = newPpObjectId(
ppId.DwgId, ppId.dbHandle, 0);
int rowIdConnector = dlm.FindAcPpRowId(ppConnectorId);
PnPRow jointRow = db.GetRow(rowIdConnector);AddRowToUniqueList(rowsToFix, jointRow);
}
}// Fix: Catches the following situations:
//
// 1. where tag does non friction match actual group
// 2. when in that location is more than than i group per function
// 3. when the relationship is missing
//
foreach (PnPRow row in rowsToFix)
{
PnPRowIdArray priorGroupIds =
dlm.GetRelatedRowIds(
"P3dLineGroupPartRelationship",
"Part", row.RowId, "LineGroup");
if (priorGroupIds.Count == 1 &&
priorGroupIds.First.Value == rowLineGroup.RowId)
{
go along;
}foreach (int id in priorGroupIds)
{
dlm.Unrelate("P3dLineGroupPartRelationship",
"LineGroup", id, "Part", row.RowId);
}dlm.Chronicle("P3dLineGroupPartRelationship",
"LineGroup", rowLineGroup.RowId, "Part", row.RowId);
}
}db.CommitTransaction();
}privatestaticvoid AddRowToUniqueList(
Listing<PnPRow> rowsToFix, PnPRow jointRow)
{
AddRowsToUniqueList(rowsToFix, newPnPRow[] { jointRow });
}privatestaticvoid AddRowsToUniqueList(
List<PnPRow> rowsToFix, PnPRow[] rowsPipes)
{
rowsToFix.AddRange(rowsPipes);
}
By Augusto Goncalves
This question came from Jens Dorstewitz: how access the P3dLineGroup of a given Establish 3D pipe? To clarify, below is the project properties with the table nosotros're looking for.
To answer we have a trouble: this information is non office of the backdrop of the piping, simply in fact stored somewhere else. And then we need to understand the relationships of Plant 3D database.
There are a few steps: (one) from a Pipe ObjectId, apply the Data Links Manager to become the RowId and (two) using the Plant 3D database, open up and search at the P3dLineGroupPartRelationship table for a row where Part equals this RowId. With this row, (3) get the LineGroup column that volition be the RowId of the line grouping we demand. Finally (4) open the P3dLineGroup table and become the row we demand. This row can be edited.
Actually Jens Dorstewitz (thanks again) wrote a sample based on this idea, below is an simplified version of information technology. Enjoy.
[CommandMethod("changeLineGroupData")]
publicvoid CmdChangeP3dLineGroupData()
{
// First, select a Plant 3D pipe
Editor ed = Awarding.DocumentManager.MdiActiveDocument.Editor;
PromptEntityOptions peo = newPromptEntityOptions(
"Select pipage to obtain properties : ");
peo.SetRejectMessage("Simply Institute 3D Pipes");
peo.AddAllowedClass(typeof(Pipe), truthful);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;ObjectId pipeId = per.ObjectId;
// Become plant 3D project part
PlantProject currentProj = PlantApplication.CurrentProject;
PipingProject pipeProj = (PipingProject)currentProj.ProjectParts["Pipe"];
DataLinksManager dlm = pipeProj.DataLinksManager;// Convert the pipe ObjectId to RowId (used on P3D database
int rowId = dlm.FindAcPpRowId(pipeId);// Go the P3dLineGroup table of the database
PnPDatabase db = dlm.GetPnPDatabase();
PnPTable tbl = db.Tables["P3dLineGroup"];// Find the relaship between the pipage RowId
// This row registry contains the P3dLineGroup
PnPRowIdArray lineGroupId = dlm.GetRelatedRowIds(
"P3dLineGroupPartRelationship", "Office", rowId, "LineGroup");
if (lineGroupId == naught || lineGroupId.Count == 0) return;
int lineGroupRowId = lineGroupId.Offset.Value;// Now select using this lineGroupRowId
string sStatement = "PnPID=" + lineGroupRowId;
PnPRow[] rows = tbl.Select(sStatement);
if (rows.Length > 0) // should be just one
{
foreach (PnPRow Row in rows)
{
// at present practise something here...
}
}
}
By Augusto Goncalves
Now that I'm near washed preparing for Plant 3D 2022 .Internet API Grooming in Moscow during AU Russian federation, here is a updated version of the training material, with slide deck and sample labs. We'll accept other API classes, see complete agenda hither.
Github: https://github.com/ADN-DevTech/Plant3DTraining
If you are attention AU Russia, we'll meet there!
Past Wayne Brill
A drawing that was edited offline has to exist re-inserted (merged) into the project. Plant drawings contain subset of project database (Blob as SQL database). Plant also a knows whether the cartoon was saved in the current project or not. If drawing was not saved in the current project, the BLOB has to exist merged into the projection.
There are several API to handle this state of affairs:
Projection.IsDrawingOutOfSync(cord dwgname, Database db) – tells whether AcDbDatabase is in sync with projection database
Project.UpdatePnPDrawing(Database db, string dwgname, ref PnPSyncConflicts conflicts) – merge blob into project database.
C# example:
[CommandMethod("testOpen", CommandFlags.Session)]
public void testOpen()
{
string strDwgPath;
Database db = new Database(simulated, true);
Project currentProject =
PlantApp.CurrentProject.ProjectParts["PnId"];
DataLinksManager dlm =
currentProject.DataLinksManager;
// go project drawing
PnPProjectDrawing pnp_dwg =
currentProject.GetDwgFileByName
("C:\\MyProject\\PID DWG\\PumpAnlage.dwg");
// use resolved path
strDwgPath = pnp_dwg.ResolvedFilePath;
db.ReadDwgFile(strDwgPath,
FileShare.ReadWrite, false, null);
// tell DLM to manage drawing database.
//(Documents are automatically enlisted
//when they are opened in editor)
dlm.EnlistDrawing(db);
// dispose will unelist information technology
if (currentProject.IsDrawingOutOfSync
(strDwgPath, db))
{
PnPSyncConflicts conflicts = null;
currentProject.UpdatePnPDrawing
(db, strDwgPath, ref conflicts);
// tell DLM that cartoon related data has to
// be saved in the project database.
// otherwise, DLM volition not save drawing sync
// timestamp causing out-of-sync
// situation on drawing open
DataLinksManager.DatabaseToForceSaveComplete
= db;
try
{
db.SaveAs(strDwgPath, DwgVersion.Current);
}
catch (System.Exception ex)
{
}
finally
{
DataLinksManager.DatabaseToForceSaveComplete
= nothing;
}
}
db.CloseInput(true);
db.Dispose();
DocumentCollection acDocMgr =
Application.DocumentManager;
Document acDoc = acDocMgr.Open(strDwgPath, imitation);
AcadDocument anAcadDoc =
(AcadDocument)acDoc.GetAcadDocument();
// if(!anAcadDoc.Saved)
anAcadDoc.Salve();
}
By Augusto Goncalves
If you lot are developing to AutoCAD Plant 3D 2022 you lot may take faced the issue beneath: 'Could not load file or assembly PnP3dObjectsMgd (….)'.
A little groundwork information: starting on 2022 release, some vertical products, like Establish 3D, are launched in plain AutoCAD with a startup modifier. This is know as configurable AutoCAD, see more than details at this weblog post. That style, the AutoCAD folder will take a subfolder /PLNT3D/ with the Plant 3D specific DLL.
Simply there is a know event where AutoCAD Plant 3D may not load some required DLLs when a plugin needs it, causing the error message mentioned.
A minor flim-flam to solve this exception is 'help' Constitute 3D discover the required DLLs. To do so, create a change your custom grade that implements IExtensionApplication. Inside the Initialize method, include:
void IExtensionApplication .Initialize()
{
AppDomain .CurrentDomain.AssemblyResolve
+= CurrentDomain_AssemblyResolve;
}
Now we can customize how and where the .NET engine will search for assemblies it could not find. Nosotros just want to include the /PLNT3D/. That can be done in several ways, here is a example:
Assembly CurrentDomain_AssemblyResolve(
object sender, ResolveEventArgs args)
{
return TryResolvePlant3D(args);
}
individual Associates TryResolvePlant3D(
ResolveEventArgs args)
{
cord name = GetAssemblyName(args);
cord assemblyPath = Arrangement.IO. Path .
Combine(PLNT3DFolder, name + ".dll" );
if (Arrangement.IO. File .Exists(assemblyPath))
{
Assembly assembly =
Assembly .LoadFrom(assemblyPath);
if (assembly.FullName == args.Name)
return assembly;
}
return null ;
}
// based on this post
private cord GetAssemblyName( ResolveEventArgs args)
{
Cord proper name;
if (args.Name.IndexOf( "," ) > -1)
proper name = args.Name.Substring(0, args.Name.IndexOf( "," ));
else
name = args.Proper name;
return name;
}
individual string PLNT3DFolder
{
go
{
return System.IO. Path .Combine(
AppDomain .CurrentDomain.BaseDirectory,
"PLNT3D" );
}
}
Past Augusto Goncalves
Nosotros're glad to publish our first DevTV on Plant 3D .NET programing. This grade will bear witness you how to get started with this API using C#. The presentation include all requirements, background data and a hands on demonstration. Use the link below to download it.
Download (42 Mb)
Want to run into more than topics covered? Leave a comment!
Past Augusto Goncalves
The pipage inline orientation can exist accessed using XAxis and ZAxis properties. From the help file, nosotros can read:
- xAxis: Input vector (in WCS) to be used to define the new aeroplane that volition contain the inline asset
- zAxis: Input X-Direction vector (WCS) for the inline asset
And, as the properties are read-merely, we can modify them using the SetOrientation method.
Despite the caption, a graphical visualization tin help we empathise the properties. After writing a small piece of code to change the properties, we tin meet the post-obit:
XAxis: modify the asset orientation regarding the flow on the pipage line, as shown on the image below.
ZAxis: rotate the nugget along the pipe line axis, helping place it properly, as shown below.
If you need to modify whatever of those directions, so observe that the vectors are unit vectors. Below is a sample code that changes both X and Z directions (just invert the values).
[CommandMethod( "assetOrient" )]
public void CmdAssetOrientation()
{
Editor ed = Awarding.DocumentManager.
MdiActiveDocument.Editor;
PromptEntityOptions peo = new
PromptEntityOptions( "Select inline asset" );
peo.SetRejectMessage( "Merely inline asset" );
peo.AddAllowedClass( typeof (PipeInlineAsset), true );
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return ;
Database db = Application.DocumentManager.
MdiActiveDocument.Database;
using (Transaction trans =
db.TransactionManager.StartTransaction())
{
PipeInlineAsset pipeAsset =
trans.GetObject(per.ObjectId, OpenMode.ForWrite)
equally PipeInlineAsset;
// go current values
Point3d position = pipeAsset.Position;
Vector3d xDir = pipeAsset.XAxis;
Vector3d zDir = pipeAsset.ZAxis;
// change the direction the nugget is comparing to the line
// for instance, a valve volition alter rotate forth the line
Vector3d zDirInverted = zDir.Negate();
// modify the orientation of the nugget
// for instace, a valve will change the in/out of the period
Vector3d xDirInverted = xDir.Negate();
// utilize the new value
pipeAsset.SetOrientation(xDirInverted, zDirInverted);
trans.Commit();
}
}
By Wayne Brill
In that location is non an API to convert an AutoCAD object to a Plant 3D pipe back up like the PlantPipeSupportConvert command does. You tin can run the command from your code notwithstanding. This c# example creates a command that has the user select the pipage and an AutoCAD entity to exist used as the support. The location of the support is the mid point of the selected pipage. The Plant 3D API is used to become the length of the pipe from the database and it is used to calculate the mid point. The PlantPipeSuportConvert command takes a betoken for the piping. (It uses an an input bespeak monitor to become the piping at that betoken).
Download Plant_3D_PipeSupportConvert
Note: Put the Plant_3D_Test_wB.dll in the PLNT3D folder to avoid errors nearly missing references. (this consequence has been reported to Plant 3D applied science)
C:\Programme Files\Autodesk\AutoCAD 2014\PLNT3D
Here is the command:
[CommandMethod("PipeSupConvert")]
public void myPlantPipeSuppportConvert()
{
Document docDocument =
AcadApp.DocumentManager.MdiActiveDocument;
Database dbDatabase = docDocument.Database;
Editor ed = docDocument.Editor;
PromptEntityOptions pmtEntOpts =
new PromptEntityOptions
("\nSelect a Pipe to connect to new Support : ");
PromptEntityResult pmtEntRes =
ed.GetEntity(pmtEntOpts);
if (pmtEntRes.Status == PromptStatus.OK)
{
Autodesk.AutoCAD.DatabaseServices.
TransactionManager tmTranMan =
dbDatabase.TransactionManager;
Transaction trans = cypher;
ObjectId oidPipeId = pmtEntRes.ObjectId;
endeavour
{
Projection currentProject =
PlantApp.CurrentProject.
ProjectParts["Pipe"];
DataLinksManager dlm =
currentProject.DataLinksManager;
PnPDatabase pnpdb =
dlm.GetPnPDatabase();
// volition use this with acedCmd to
// send the command
ResultBuffer rb = new ResultBuffer();
trans = tmTranMan.StartTransaction();
Pipage supP3DPipe = trans.GetObject
(oidPipeId, OpenMode.ForRead) as Pipe;
if (supP3DPipe == null)
{
ed.WriteMessage
("\due north Selected entity is not a Plant 3D Pipe");
}
else
{
// Output the ObjectId of the
//Piping for bank check purposes
// ed.WriteMessage
//("\n ObjectId of the Pipe : {0}", oidPipeId);
// Go Matrix3d of the selected
// piping to excerpt its Xaxis
Matrix3d suppM3D =
((Entity)supP3DPipe).Ecs;
// Go the RowId of the Pipe in
// the Found 3D project database
int iPipeRowId =
dlm.FindAcPpRowId(oidPipeId);
// Get the corresponding PnPRow
// of the Pipe
PnPRow ppRow =
pnpdb.GetRow(iPipeRowId);
// Become the insertion bespeak of
// the selected Pipe
Point3d p3dPipePosition =
new Point3d(
Convert.ToDouble(ppRow["Position Ten"]),
Convert.ToDouble(ppRow["Position Y"]),
Convert.ToDouble(ppRow["Position Z"]));
// Get the Pipe length from the
// Plant 3D project database
double dPipeLength =
Convert.ToDouble(ppRow["Length"]);
// Get the position of the
// middle of the selected Pipe
Point3d p3dSupportInsertionPoint =
new Point3d(
p3dPipePosition.X + dPipeLength *
suppM3D.CoordinateSystem3d.Xaxis.10 / ii,
p3dPipePosition.Y + dPipeLength *
suppM3D.CoordinateSystem3d.Xaxis.Y / 2,
p3dPipePosition.Z + dPipeLength *
suppM3D.CoordinateSystem3d.Xaxis.Z / 2);
// Commit the transaction take
// all the data now
trans.Commit();
pmtEntOpts = new PromptEntityOptions
("\nSelect AutoCad entity to be converted : ");
pmtEntRes = ed.GetEntity(pmtEntOpts);
if (pmtEntRes.Condition ==
PromptStatus.OK)
{
ObjectId oidEntityId =
pmtEntRes.ObjectId;
// Add the command to the ResBuf
rb.Add(new TypedValue
(5005, "_PlantPipeSupportConvert"));
// Add together the selected
// entity ObjectId
rb.Add(new TypedValue
(5006, oidEntityId));
// return on the control line
rb.Add together(new TypedValue(5005, ""));
// mid point of the selected pipe
rb.Add(new TypedValue
(5009, p3dSupportInsertionPoint));
acedCmd(rb.UnmanagedObject);
}
}
}
take hold of
{
if (trans != nil)
{
trans.Arrest();
trans.Dispose();
}
}
}
}
past Fenton Webb
I of my developers was trying to create a toolbar button which automatically setup some text styles/parameters. Everything was fine except that on some machines, the button would fail – the fault was "Font file doesn't exist". He was using a very commonly used font file "arial.ttf", indeed arial.ttf is the default font for the "Standard" AutoCAD way.
It seems there are very important updates the Font packs that you need to include (update) with your Windows installation – check out http://www.microsoft.com/typography/fonts/
I'1000 guessing Windows update also includes these Font updates every bit 'Optional' – best install them for an easy life!
by Fenton Webb
If you are creating some sort of converter tool between AutoCAD Plant3d and some other product you are more than likely going to need to gain admission to the raw geometry that makes up Plant3d objects, and, in addition yous volition also demand to catch the property names and values of those objects.
In that location are 2 ways to obtain the 3dSolid information from Plant3d objects…
- The starting time way is to explode() a Plant3d object until you receive Solid3d objects. Once you have the Solid3d objects, you can and so use the BREP API to extract the purlieus representation of the solids. This option is the quickest to implement, still, the interpretation of the geometry is going to be tricky (at least for me it is).
- The second way is to create custom WorldDraw and ViewportDraw classes (in ObjectARX they are chosen AcGiWorldDraw and AcgiViewprtDraw). By doing this, you tin essentially override the low level depict routines that AutoCAD uses and supplant them with your own functions which tin can exist used to work out the geometrical data that is being drawn. A good case of how this works can be found in the ObjectARX sample called acgisamp. Check out this post on How AcDb3dSolids are drawn when using a custom derived AcGiWorldDraw. This option is going to be much more than work to implement, merely once yous have information technology implemented then extracting the geometrical shapes volition exist much easier.
And so, yous are of form going to need to match the geometry properties of the solid with the actual geometry of the role… To do this, you can either use the DataLinksManager or the Part/SubPart.PartSizeProperties()
Source: https://adndevblog.typepad.com/autocad/plant3d/page/2/
0 Response to "draw a pipe in autocad 3d"
Post a Comment