cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - If community subscription notifications are filling up your inbox you can set up a daily digest and get all your notifications in a single email. X

Translate the entire conversation x

Get WTPart attribute for associated EPM model OR drawing

Dobi
16-Pearl

Get WTPart attribute for associated EPM model OR drawing

Version: Windchill 13.0

 

Use Case: Working on getting specific WTPart attributes overlaid on published drawing PDFs.


Description:

I thought this would be simple enough but I ended up struggling the last two days in trying to achieve the following:

  • Code collects and makes available an EPMDocument ID. ✔️
    • EPMDocument could be either a drawing or a model and it will have an associated WTPart. 

If this is a drawing:

EPMStructureHelper.service.navigateReferences(etc etc)

instead... from here I can't resolve either the EPMReferenceLink IDs or the EPMDocumentMasters (depending on the boolean settings) to get the related model. 

 

It's not clear to me where to go to get the "rolename" values or "buildrule" integer values to be able to go directly from the drawing to the WTPart. That would be ideal. 

 

There's CS351622 that goes over how to fetch an owner linked WTPart. Assuming here that if I change "OWNER" to "IMAGE" or "CALCULATED" (?) this may give me what I want? 

 

I just feel like I'm missing some pretty important pages from some customization guide somewhere... 

ACCEPTED SOLUTION

Accepted Solutions
joe_morton
17-Peridot
(To:Dobi)

I think you'll have to split the code into two cases:

  • If the EPMDocument you start with is a model, it should be pretty straightforward to get the WTPart.
  • If the EPMDocument you start with is a drawing (with calculated link to WTPart), you'll have to navigate from drawing -> model master -> version of model you want (latest?) -> WTPart

From drawings, Windchill stores at least 3 types of links to other CAD files:

  • Drawing Reference - the model added directly to the drawing. This is the one you want, but there can be multiple of these!
  • Default - additional references (child components in an assembly, for example)
  • Drawing Format Reference

Not a full solution, but hope that helps point you in the right direction

 

Something you may want to consider as a shortcut would be if you have any numbering conventions for your models / drawings / WTParts. We, for instance, basically match the number on all three, so as long as things are numbered correctly (BIG IF), I could use the number from the first EPMDocument, then run a query to get the WTPart with the number that corresponds.

View solution in original post

11 REPLIES 11

What type of link are you using to link the WTPart and CAD drawing?

Image and Calculated?

Not Content?

Dobi
16-Pearl
(To:d_graham)

Generally, the drawing will only ever be calculated. The model could be either image or owner but not content.

I meant is the drawing a Content link not the model. Regardless as long as we know it’s Calculated link that all we need to know.

 

Do you understand what a calculated link is?

Meaning how it is calculated?

Dobi
16-Pearl
(To:d_graham)

The drawing is a calculated link to the WTPart. 

MalteSiefkes
13-Aquamarine
(To:Dobi)

From your description, it seems you are looking to navigate the DescribedBy from a WTPart to an EPMDocument Drawing?
You might want to chceck:
- https://www.ptc.com/en/support/article/CS131357
- https://www.ptc.com/en/support/article/CS240504
- https://support.ptc.com/help/windchill/r13.1.0.0/en/#page/Windchill_Help_Center/ManagingCADandPartRelationships/MCPR_AssociationOview.html

This code snippet may help:
wt.fc.collections.WTCollection parts = new wt.fc.collections.WTArrayList();
parts.add(part);
wt.fc.collections.WTKeyedMap associatedCADDocumentMap = ((wt.part.StandardPartDocService)wt.part.PartDocHelper.service).getAssociatedCADDocuments(parts);

@MalteSiefkes 

I'm looking to navigate the opposite way: from an EPMDocument (either drawing or model) to a WTPart. 

 

So likely this may give me what I want:

com.ptc.windchill.collector.api.cad

getAssociatedParts(EPMDocument seed)

 

joe_morton
17-Peridot
(To:Dobi)

I think you'll have to split the code into two cases:

  • If the EPMDocument you start with is a model, it should be pretty straightforward to get the WTPart.
  • If the EPMDocument you start with is a drawing (with calculated link to WTPart), you'll have to navigate from drawing -> model master -> version of model you want (latest?) -> WTPart

From drawings, Windchill stores at least 3 types of links to other CAD files:

  • Drawing Reference - the model added directly to the drawing. This is the one you want, but there can be multiple of these!
  • Default - additional references (child components in an assembly, for example)
  • Drawing Format Reference

Not a full solution, but hope that helps point you in the right direction

 

Something you may want to consider as a shortcut would be if you have any numbering conventions for your models / drawings / WTParts. We, for instance, basically match the number on all three, so as long as things are numbered correctly (BIG IF), I could use the number from the first EPMDocument, then run a query to get the WTPart with the number that corresponds.

@joe_morton ,

This tracks... 

 

If I pass in a CADDRAWING docType (using a version of this code from CS35845 that @MalteSiefkes 's links at some point led to) I get the result you point out:

[PublisherQueue1.PollingThread] wt.system.out Administrator - EPMDocument: wt.epm.EPMDocument:128051679 collected
[PublisherQueue1.PollingThread] wt.system.out Administrator - Put results.iterator into items: [wt.epm.EPMDocument:128051679]
[PublisherQueue1.PollingThread] wt.system.out Administrator - Prt variable is still null... see: null

 

If the incoming EPM is a CADCOMPONENT docType (i.e. Model) then the result collects the associated WTPart.

[PublisherQueue1.PollingThread] wt.system.out Administrator - EPMDocument: wt.epm.EPMDocument:128037137 collected
[PublisherQueue1.PollingThread] wt.system.out Administrator - Put results.iterator into items: [wt.epm.EPMDocument:128037137, wt.part.WTPart:128037156]
[PublisherQueue1.PollingThread] wt.system.out Administrator - Part:<part info i want goes here>

 

This is close to the path I was on (already have logic for `if CADDRAWING then get CADCOMPONENT` in my code). 

 

The numbering way is my plan B if this doesn't work. While we do have matching numbers (in theory...) I've seen typos more often than I would like. 

MalteSiefkes
13-Aquamarine
(To:Dobi)

Hello,

 

I can confirm that the methods

wt.part.PartDocHelper.service.getAssociatedCADDocuments

wt.part.PartDocHelper.service.getAssociatedEPMDescribeLinks

consider calculated links for given part, the later returns specifically only the required drawing.

 

For the reverse I found no applicable, supported API which considers the calculated link. As discussed, this apparently requires a two-step.

For this I checked CadCollector.GatherDependents.ONLY_REQUIRED, but it returns all Models associated to the drawing (incl. the lower CAD Models used in an Assembly).

For finding the main model from the Drawing, I only found as supported option the use of a QuerySpec:

 

wt.query.QuerySpec querySpec = new wt.query.QuerySpec();
int linkIndex = querySpec.addClassList(wt.epm.structure.EPMReferenceLink.class, true);
int[] indices = { linkIndex };
querySpec.setDescendantsIncluded(true, linkIndex);
querySpec.appendWhere(new wt.query.SearchCondition(wt.epm.structure.EPMReferenceLink.class, wt.epm.structure.EPMReferenceLink.REFERENCE_TYPE, "LIKE", "DRAWING"), indices);

wt.epm.EPMDocConfigSpec configSpec = new wt.epm.EPMDocConfigSpec();
configSpec.setAsStoredActive(true);

wt.fc.QueryResult queryResult= wt.epm.structure.EPMStructureHelper.service.navigateReferencesToIteration(epmdocument, querySpec, configSpec);

 

I provide above as pure "seems to work for me" and cannot provide any support on it. If needed, please open up a case with PTC Technical Support.

It would be great if you could create a Product Idea "Need supported API to retrieve for a given Drawing the corresponding main WTPart (considering calculated links)".

 

Kind regards

 

Malte

Thanks everyone for the help! I got it working. 

 

It was a two-step approach for me since my incoming item could be either a model or drawing. 

For going from drawing to WTPart attribute it ended up looking something like this:

 

EPMDocument cadDoc = //whatever gets passed in to this method;

if(cadDoc.getDocType().toString().equals("CADDRAWING")) { 
   // get the WTPart attribute for the drawing
   String atr = myGetWTPartAttributeValue(cadDoc);
}

 

In the getWTPartAttribute method I went the route of what was written up in CS358450

 

java.util.Collection<?> result = null;
wt.fc.collections.WTCollection seeds = new wt.fc.collections.WTArrayList();

model = getModelFromDrawing(epm); //when incoming EPM is drawing
seeds.add(model); 

wt.epm.EPMDocConfigSpec configSpec = new wt.epm.EPMDocConfigSpec();
configSpec.setLatestActive();

wt.filter.NavigationCriteria nc = wt.filter.NavigationCriteria.newNavigationCriteria();
java.util.List<wt.epm.EPMDocConfigSpec> configpecs = new java.util.ArrayList<wt.epm.EPMDocConfigSpec>();
		configpecs.add(configSpec);
		nc.setConfigSpecs(configpecs);
		com.ptc.windchill.collector.api.CollectedResult ccr = null;
		ccr = com.ptc.windchill.collector.api.cad.CadCollector.newInstance(seeds, nc).associatedParts(com.ptc.windchill.collector.api.cad.CadCollector.GatherAssociatedParts.ONLY_FOR_SEEDS).collect(); 
result = ccr.getCollectedObjects();
java.util.Iterator<?> items = result.iterator();
		
while (items.hasNext()) {
    Object item = items.next();
    if (item instanceof wt.part.WTPart) {
	prt = (wt.part.WTPart) item; 
    }
}

// then use PersistableAdapter to get my WTPart value
com.ptc.core.lwc.server.PersistableAdapter obj = new com.ptc.core.lwc.server.PersistableAdapter(prt,null,null, new com.ptc.core.meta.common.DisplayOperationIdentifier());
        try {
			obj.load("myAttribute");
			ret = (String)obj.get("myAttribute");
			return ret;
		}

 

And to get the model from the drawing @joe_morton 's way worked just fine with this as the base and VersionControlHelper.service for the rest:

QueryResult qr = EPMStructureHelper.service.navigateReferences(drawing, null, false); // this returns EPMReferences

while (qr.hasMoreElements() && qr != null) { 			
   EPMReferenceLink link = (EPMReferenceLink)qr.nextElement();
   if(link.getDepType()==4) {
      epmMaster = (EPMDocumentMaster)link.getReferences();
      // other checks happen here to verify number matches in case of multiple references
   }
}

QueryResult verQr = VersionControlHelper.service.allIterationsOf(epmMaster);
while (verQr.hasMoreElements()) {
   Iterated itr = VersionControlHelper.service.getLatestIteration((Iterated)verQr.nextElement(), false);
   model = (EPMDocument)itr;
   // other checks go here
}
		
return model;

 

@MalteSiefkes I don't think so.

 

@Dobi stated the link is Calculated.  Therefore, he needs to write his own code to go from Drawing to WTPart or WTPart to drawing.

I've recently had to do this myself. It's a lot more complicated than navigating an object to object link or version to version link or an object to master link.

Announcements
Top Tags