Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The Discovery Application Programming Interface \(API\) Developer Guide contains

This document contains information on the following:

- The basic infrastructure for Add-in customization.
- The basic infrastructure for add-in customization.
- How to add custom elements to the User Interface.
- An overview of the geometry architecture.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Getting started

The Discovery extensibility shares the same architecture as the SpaceClaim Add-in based customization. As a result of this design, many of the extensibility related APIs are coming from the `SpaceClaim.Api.V22 dll`. The physics related Discovery APIs, as well as some UI extensibility APIs that are specific to the Discovery product, are found in the `Discovery.Api.V22.dll`. There is no forward compatibility between SpaceClaim and Discovery Add-in, but the underlying architecture is the same: an Add-in that uses the SpaceClaim APIs to customize the User Interface will typically need some tweaks and adjustments to account for the difference in the User Interface between the two products. On the other hand, the geometry APIs used in a SpaceClaim add-in are fully functional in Discovery.
The Discovery extensibility shares the same architecture as the SpaceClaim Add-in based customization. As a result of this design, many of the extensibility related APIs are coming from the `SpaceClaim.Api.V22 dll`. The physics related Discovery APIs, as well as some UI extensibility APIs that are specific to the Discovery product, are found in the `Discovery.Api.V22.dll`. There is no forward compatibility between SpaceClaim and Discovery Add-in, but the underlying architecture is the same: an add-in that uses the SpaceClaim APIs to customize the User Interface will typically need some tweaks and adjustments to account for the difference in the User Interface between the two products. On the other hand, the geometry APIs used in a SpaceClaim add-in are fully functional in Discovery.

A Discovery add-in is a .NET class library assembly that implements at a minimum the IExtensibility interface. This interface provides the entry point for the add-in and allows the add-in to perform any initialization.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Discovery will search for manifest files in all of the following areas:

**Notes:**

1. Putting the manifest file in the ProgramData\\Discovery\\Addins directory is the approach to follow when an Add-in should only be visible for a single user.
1. Putting the manifest file in the ProgramData\\Discovery\\Addins directory is the approach to follow when an add-in should only be visible for a single user.
2. Putting the manifest file in the Addins folder inside the Discovery installation folder typically requires Administrative privileges and should be done for add-ins that are installed as part of Discovery.
3. Creating a string value in the add-ins registry is the recommended approach when a third party add-in is installed. This way, Discovery and the add-in do not need to know where each other is installed.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ The Sample Add-in project \(C\#\) contains programming examples of how to use va

## Add-ins frequently asked questions

1. **What can I do when my Add-in project can’t build because it’s missing references or packages? Add-ins require several Discovery DLL libraries:**
1. **What can I do when my add-in project can’t build because it’s missing references or packages? Add-ins require several Discovery DLL libraries:**

`Discovery.API.2X`

`SpaceClaim.API.2X`

`SpaceClaim.API.2X.Internal`

2. **What can I do when my Add-in project is built, but I can’t see it in Discovery?**
2. **What can I do when my add-in project is built, but I can’t see it in Discovery?**

Either the Add-in is not completely built, or it is just not visible on Discovery.
Either the add-in is not completely built, or it is just not visible on Discovery.

Check Discovery Settings \> Add-in and determine if the add-in is present. If it’s found, go to the Ribbon section in the advanced part.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class CustomTool : Tool
}
```

This XML defines the layout and structure of the options panel for a custom tool.

```
<?xml version="1.0" encoding="utf-8"?>
<customUI xmlns="http://schemas.spaceclaim.com/customui">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"build": {
"globalMetadata": {
"title": "Discovery Extensibility and Add-ins developer guide 2024 R2_3",
"title": "Discovery Extensibility and Add-ins Developer Guide 2024 R2",
"summary": "",
"version": "2024 R2",
"product": "Discovery",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
###############
# folder #
###############
/**/DROP/
/**/TEMP/
/**/packages/
/**/bin/
/**/obj/
_site
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
StylesPath = styles

MinAlertLevel = suggestion

Packages = Google

Vocab = ansys

[*.md]
Ignore = articles/shared/c_legal_frontmatter.md
BasedOnStyles = Vale, Google
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
###############
# temp file #
###############
*.yml
.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# PLACEHOLDER
TODO: Add .NET projects to the *src* folder and run `docfx` to generate **REAL** *API Documentation*.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Accuracy

This section covers the following topics:

- **[Linear and angular resolution](../../../../UDA/add_api/architecture/accuracy/linear_angular_res.md)**

- **[Comparing lengths and angles](../../../../UDA/add_api/architecture/accuracy/compare_angles_lengths.md)**

- **[Comparing XYZ objects](../../../../UDA/add_api/architecture/accuracy/compare_xyz.md)**

- **[Comparing UV objects](../../../../UDA/add_api/architecture/accuracy/compare_uv.md)**

- **[Comparing geometry](../../../../UDA/add_api/architecture/accuracy/compare_geo.md)**



Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Comparing lengths and angles

The Accuracy class provides methods for comparing lengths and angles.

The CompareLengths method takes two arguments, *lengthA* and *lengthB*, and returns an integer result:

- -1 *lengthA* is less than *lengthB*.
- 0 *lengthA* is equal to *lengthB* to within linear resolution.
- +1 *lengthA* is greater than *lengthB*.

This method provides general comparison of two lengths, but for common situations, such as comparing with zero, or testing whether two values are equal, simpler and more readable methods can be used:

```
public static void Example(double lengthA, double lengthB) {
// same as CompareLengths(lengthA, lengthB) == 0
bool equalLengths = Accuracy.EqualLengths(lengthA, lengthB);

// same as CompareLengths(lengthA, 0) == 0
bool lengthIsZero = Accuracy.LengthIsZero(lengthA);

// same as CompareLengths(lengthA, 0) > 0
bool lengthIsPositive = Accuracy.LengthIsPositive(lengthA);

// same as CompareLengths(lengthA, 0) < 0
bool lengthIsNegative = Accuracy.LengthIsNegative(lengthA);
}

```

Corresponding methods are provided for angles: CompareAngles, EqualAngles, AngleIsZero, AngleIsPositive, and AngleIsNegative.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Comparing geometry

To say that two surfaces or two curves are equal is ambiguous, since there is more than one interpretation of the concept. For example, with two planes:

- They could be coplanar, but the normals could be opposed.
- They could be coplanar, with normals having the same sense, but their frames and hence their parameterization might be different.
- They might be identical in every way.

You should not use the == operator with surface and curve types, since that will only test for reference equality.

`Geometry.IsCoincident` and `ITrimmedCurve.lsCoincident` are provided to make comparisons. They only test for coincidence, which means any of the above cases would pass.


Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Comparing UV objects

The same isn't true for the surface parameter UV types, PointUV, VectorUV, DirectionUV, and BoxUV, or for the curve parameter type, Interval. These types don't know whether the parameterization they represent is linear, angular, or some other type. For example, for a plane, the U parameterization is linear, but for a cylinder, the U parameterization is angular. For a NURBS surface, the U parameterization is neither linear nor angular.

Therefore, you shouldn't use the == operator for these types. When comparing parameters, you should use the appropriate length or angle comparison method for each of the U and V values. For NURBS parameterization, angular comparison could be used, but it's safest to evaluate points and compare these instead.


Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Comparing XYZ objects

The basic XYZ types, Point, Vector, Direction, Box, and Frame, have resolution tests build in, so you can compare objects using the == operator. For example, two points are equal if the distance between them is less than the linear resolution, and two directions are equal if the angle between them is less than then angular resolution.

```
public static void Example(Plane plane, Point point) {
// project point onto plane
SurfaceEvaluation eval = plane.ProjectPoint(point);
Point pointOnPlane = eval.Point;

// points are the same if less than linear resolution apart
bool planeContainsPoint = point == pointOnPlane;

// ContainsPoint is more efficient, but gives the same result
Debug.Assert(planeContainsPoint == plane.ContainsPoint(point));
}

```


Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Linear and angular resolution

Internally, geometric calculations are performed to machine double precision. When comparing the results of calculations, values should always be compared to within a specific resolution. These resolutions are provided by the Accuracy class:

- Two lengths are considered equal if their difference is less than LinearResolution.
- Two angles are considered equal if their difference is less than AngularResolution.

For example, when ContainsPoint is called to determine whether a point lies in a surface, internally the distance from the surface might be calculated, and the result is true if this distance is less than LinearResolution.


Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Application integration

This section covers the following topics:

- **[Persistent identifiers](../../../../UDA/add_api/architecture/application_integration/persist_ids.md)**

- **[Replacements](../../../../UDA/add_api/architecture/application_integration/replacements.md)**

- **[Update states](../../../../UDA/add_api/architecture/application_integration/update_states.md)**


Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Persistent identifiers

Doc objects have persistent identifiers, called *monikers*, which can be recorded and later *resolved* to return the doc object again. The Moniker property returns a moniker for the doc object, and the Resolve method returns the doc object again.

Internally, master doc objects have an identifier, which is globally unique. Occurrences are identified by the instance, which is a master, along with the original object, which might itself be an occurrence. A moniker is an object that encapsulates the identifiers of the one or more master objects involved in the identity of the subject.

To record a moniker, you can record its string representation using ToString. The length of this string depends on the number of master objects involved. The format of this string isn't documented, so you shouldn't attempt to construct or modify such a string.

To convert the string representation back into a moniker, you can use `FromString`.

```
public static void Example(IDesignFace desFace) {
Document doc = desFace.Document;

// all doc objects provide a moniker
Moniker<IDesignFace> desFaceMonikerA = desFace.Moniker;

// resolve the moniker in the document to obtain the original object
Debug.Assert(desFaceMonikerA.Resolve(doc) == desFace);

// the string representation can be recorded
string monikerText = desFaceMonikerA.ToString();

// the moniker can be reconstructed from the string
Moniker<IDesignFace> desFaceMonikerB = Moniker<IDesignFace>.FromString(monikerText);
Debug.Assert(desFaceMonikerB.Resolve(doc) == desFace);
}

```

To resolve a moniker, a document must be provided as the context. Discovery allows more than one version of the same scdoc file to be loaded at the same time, so the same moniker could potentially be resolved in more than one document.

Since the internal identifiers involved are globally unique, there is no danger of resolving the moniker in an unrelated document. If you attempt to do so, `null` will be returned to indicate that the object was not found.


Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Replacements

If the doc object has been deleted, Resolve returns null to indicate that the object was not found. Sometimes doc objects can get replaced during a command. For example, if a design face is split during a modeling operation, it will be replaced by two new design faces. Perhaps one of these new design faces gets split itself, or perhaps one of them gets deleted.

Behind the scenes, replacements are recorded, and when Resolve is called, if the object has been replaced, the moniker automatically returns one of the survivors, or null if there are no survivors.

- If it is important to know whether the object is a survivor, rather than the original object, you can compare its moniker with the moniker you already have, using the == operator. If the object is a survivor, it will have a different moniker.
- If it is important to obtain all survivors, ResolveSurvivors can be used instead. Note that this method only returns surviving replacements, so if the object hasn't been replaced at all, no survivors are returned.


Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Update states

A doc object master has an *update state*, which tells you if the object has changed.

Each time the doc object master is changed, its update state changes. Conversely, if the update state hasn't changed, then the object hasn't changed. When an object is changed due to an undo \(or redo\) operation, its update state is undone \(or redone\) too.

The update state is persistent, so you can store its string representation and use it in another Discovery session.

```
public static void Example(DesignFace desFace) {
// doc object masters provide an update state
UpdateState beforeStateA = desFace.UpdateState;

// the string representation can be recorded
string stateText = beforeStateA.ToString();

ModifyDesignBody();

// test whether the design face was changed
if (desFace.UpdateState != beforeStateA)
Debug.WriteLine("Design face was changed.");

// the update state can be reconstructed from the string
UpdateState beforeStateB = UpdateState.FromString(stateText);
Debug.Assert(beforeStateA == beforeStateB);
}

```

Update states aren't provided for occurrences, but you can store the update states of the instances involved in the occurrence chain, along with the update state of the master. PathToMaster returns these instances.

The update state only represents the state of the object itself, and not the state of other objects it contains or references. For example, the update state of a part isn't changed if a child design body is modified. Similarly, although the update state of a component will change if its placement is modified \(since this is a property of the component itself\), the update state won't change if its template part is modified.


Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Geometry architecture

This section discusses the geometry architecture and includes the following sections:

- **[Documents and doc objects](../../../UDA/add_api/architecture/doc_objects/document_doc_objects.md)**

- **[Application integration](../../../UDA/add_api/architecture/application_integration/app_integration.md)**

- **[Storing custom data](../../../UDA/add_api/architecture/storing_custom_data/storing_custom_data.md)**

- **[Identifiers during export](../../../UDA/add_api/architecture/id_objects/ID_during_export.md)**

- **[Geometry and topology](../../../UDA/add_api/architecture/geo_topology/geo_topology.md)**

- **[Accuracy](../../../UDA/add_api/architecture/accuracy/accuracy.md)**

- **[Units](../../../UDA/add_api/architecture/units/units.md)**


Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Documents and doc objects

A Document is the unit of loading and saving. Assuming it has been saved, a document corresponds to a Discovery scdoc file on disk.

A DocObject is an object that belongs to a document. Doc objects aren't the only objects that get saved when the document is saved, but they are the only objects that have a Document property. Examples of doc objects include: Part, Component, DesignBody, DesignFace, DatumPlane, and Note.

Doc objects provide:

- A parent-child tree containment hierarchy.
- Monikers for persistent identification.
- Update states to indicate that the doc object has changed.
- Custom attributes for storing third party data.

This section contains the following topics:

- **[Parent-child hierarchy](../../../../UDA/add_api/architecture/doc_objects/parent_child_hierarchy.md)**

- **[Parts and components](../../../../UDA/add_api/architecture/doc_objects/parts_components.md)**

- **[Occurrence chains](../../../../UDA/add_api/architecture/doc_objects/occurrence_chains.md)**

- **[General objects and masters](../../../../UDA/add_api/architecture/doc_objects/gen_objects_masters.md)**

- **[Originals and masters](../../../../UDA/add_api/architecture/doc_objects/originals_masters.md)**

- **[Transforming to master-space](../../../../UDA/add_api/architecture/doc_objects/transform_master_space.md)**

- **[Getting occurrences](../../../../UDA/add_api/architecture/doc_objects/getting_occurrences.md)**



Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# General objects and masters

In general, a doc object is either an occurrence, or a *master*. When dealing with *general* doc objects \(doc objects that might be occurrences or masters\), interfaces are used, for example, IPart, IComponent, and IDesignBody. These all derive from IDocObject.

There are some methods and properties that for theoretical or practical reasons aren't presented by occurrences, and are therefore only presented by masters. When dealing with masters, classes are used, for example, Part, Component, and DesignBody. These all derived from DocObject, which implements IDocObject.

Part implements IPart, Component implements IComponent, and so on, so a master supports everything that a general object supports, and often more besides.

Note that although Part is always a root object, IPart may or may not be a root object. If the IPart happens to be a master, then it's a root object, but if it happens to be an occurrence, its parent will be an IComponent or an IDrawingView.


Loading