Skip to main content
1-Visitor
March 16, 2012
Question

layers - a popular topic this week.

  • March 16, 2012
  • 26 replies
  • 12087 views
Greetings,



I have a good reason to finally learn what "Isolate" layers are and how they
work. I am looking for a layers tutorial or overview. I remember the last
time I went to the World Event, 2007, Glen Beer gave a terrific seminar on
this. I left there full of ambition to tame my layers, but never found a
round tuit. Until now.



Glen, are you out there? Anybody else know this crazy layer thing and can
point me to some learnin'?



Thanks,



-Nate

26 replies

12-Amethyst
March 20, 2012

Damn double post.. sorry.

12-Amethyst
March 20, 2012

ModelCHECK does this in a couple clicks. And without the need to bloat up a config.pro file with an enormous mapkey.


The only thing it doesn't do is add in layer rules. But, running model check will place most items on their correct layers, so that becomes nearly a moot point.


It also does parameters, checks if correct views exist, relations, formats, dtl files, tolerance type, accuracy, units, early rounds/chamfers, edge references, unused planes, materials, and so forth.




In Reply to alfonso medina:


So how do you guys feel about layer rules? Basically you go to a layer and
in its properties you can set up a search rule where it can find certain
items and put them in the layer. That can also be set to "associative"
which really means automatic. If you set it to automatic, then any new
plane goes into the plane folder, and any new feature named for example
"cool_feature_XX" could also be automagically pulled into a specific layer.

My start parts have their layers set to hidden by default. For any older
part or badly imported OTS part I made a map key to create the layers and
set them up with the rules. But then this took a few too many seconds. So I
wrote a Jlink up to not only fix the layers but also create views and check
parameters and remove un used ones. The jlink version runs probably 20 to
50 times faster. Setting rules tends to be the slow part. The views are
created in the blink of an eye and same for parameter checking.

My next step is to make this a batch script and just fix everything once
and for all. I'm tired of opening a part and having to click a thousand
times to get rid of the mess of planes and lines and points and coordinate
systems and notes and surfaces and the kitchen sink. Just tired of it.
Maybe I'll post a write up. I'll post the source code in a few. Its a
modification of some other jlink stuff I found on the internets.

regards,

Alfonso


1-Visitor
March 20, 2012
I'm still using the layera and layerp because setting those to
"associative" seems to be missing in Jlink but here is my code that uses
these mapkeys and also creates views and checks parameters. parameter
checking comprises of removing crap parameters so use with caution. You can
make that part smarter:


// Copyright 2012, Alfonso Medina
// This program adds several views to a part
package WSFIX;
// imports required
import com.ptc.cipjava.*;
import com.ptc.pfc.pfcBase.*;
import com.ptc.pfc.pfcCommand.*;
import com.ptc.pfc.pfcGlobal.*;
import com.ptc.pfc.pfcLayer.Layer;
import com.ptc.pfc.pfcLayer.Layers;
import com.ptc.pfc.pfcModel.*;
import com.ptc.pfc.pfcModel2D.*;
import com.ptc.pfc.pfcModelItem.*;
import com.ptc.pfc.pfcTable.*;
import com.ptc.pfc.pfcSession.BaseSession.*;
import com.ptc.pfc.pfcSelect.*;
import com.ptc.pfc.pfcSession.*;
import com.ptc.pfc.pfcView.*;
import com.ptc.pfc.pfcWindow.pfcWindow;
import com.ptc.pfc.pfcWindow.Window;
import java.io.*;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;


public class View_Fix {
//String install_directory = System.getenv("INSTALL_DIRECTORY");
static View_Fix App = null;
String programName = null;
Session session = null;
FileWriter log = null;
FileWriter TabBOM = null;
String msgFile = "C:/apps/ptc/WSFIX/text/VIEWS_FIXED.txt";
String newline = null;
//Synch.TextEr.Area(args);
// constructor
//
public View_Fix () {
programName = this.getClass().getName();
try {
log = new FileWriter("C:/apps/ptc/ViewFix.log");
newline = System.getProperty("line.separator");
}
catch (Exception e) {
// couldn't create log file, ignore
}
}



// Display message in Pro/Engineer
//
public void DisplayMessage ( String mesg ) throws Exception {
stringseq seq = stringseq.create();
seq.set(0, mesg);
session.UIDisplayMessage(msgFile, "WSFX %s", seq);
seq.clear();
writeLog(mesg);
}

// Write text to log file
//
public void writeLog ( String mesg ) {
try {
if (log == null) { return; }
log.write(mesg + newline);
log.flush();
}
catch (Exception e) {
// ignore
}
}
// Write text to log file
//
public void tableBOM ( String mesg ) {
try {
if (TabBOM == null) { return; }
TabBOM.write(mesg + newline);
TabBOM.flush();
}
catch (Exception e) {
// ignore
}
}



// Close all log file
//
public void closeBOM () {
try {
if (TabBOM == null) { return; }
TabBOM.close();
}
catch (Exception e) {
// ignore
}
}
// Close all log file
//
public void closeLog () {
try {
if (log == null) { return; }
log.close();
}
catch (Exception e) {
// ignore
}
}

// Called by Pro/Engineer when starting the application
//
public static void startApp () {
try {
App = new View_Fix();
App.startupApplication();
}
catch (Exception e) {
App.writeLog("Problem running startupApplication method" +
e.toString());
return;
}
}

// Called by Pro/Engineer when stopping the application
//
public static void stopApp () {
try {
App.shutdownApplication();
}
catch (Exception e) {
App.writeLog("Problem running shutdownApplication method" +
e.toString());
return;
}
}

// Perform some steps when shutting down the application
//
public void shutdownApplication () throws Exception {
writeLog("Application " + programName + " stopped");
closeLog();
}

// Perform some steps when starting the application
//
public void startupApplication () throws Exception {

try {
writeLog("Application " + programName + " started.");
session = pfcGlobal.GetProESession();
}
catch (jxthrowable x) {
writeLog("ERROR: Problem getting session object.");
return;
}

UICommand BTNtablefix = null;

try {
// Define a UI command
BTNtablefix = session.UICreateCommand(
"WSFX Btn2 Cmd", new WSFX_Btn1_CmdListener()
);
}
catch (jxthrowable x) {
writeLog("ERROR: Problem creating uicmd.");
return;
}

try {
// Add UI command to 'Tools' menu
session.UIAddButton(BTNtablefix, "Utilities", null,"WSFX Btn2
Label", "WSFX Btn2 Help","msg_wsfix.txt");
}
catch (jxthrowable x) {
writeLog("ERROR: Problem creating menu: " + x.toString());
return;
}

DisplayMessage(programName + " application started.");

}

// Callback for the 'Tools' menu button
//
public void Btn1_callback ( ) throws Exception {
TabBOM = new FileWriter("C:/apps/ptc/WSFIX/FIXED.txt");
String mesg = null;


Model model = session.GetCurrentModel();
Model currentModel;
Tables tables;
int index = -1, qty =-1, part=-1, desc=-1,tmp=-1,len=-1;
stringseq seq = stringseq.create();
if (model == null) {
mesg = "Hello!";
}
else {
mesg = "Hello! The model is: " + model.GetFileName();
}

DisplayMessage(mesg);

currentModel = (Model) model;
currentModel.RetrieveView("FRONT");
currentModel.SaveView("FRONT");
View view = currentModel.GetCurrentView();
view.SetTransform(normalize(view.GetTransform()));
view.Rotate(CoordAxis.COORD_AXIS_Y, 90.0);
currentModel.SaveView("LEFT");
currentModel.SaveView("LSIDE");
view.Rotate(CoordAxis.COORD_AXIS_Y, 90.0);
currentModel.SaveView("REAR");
currentModel.SaveView("BACK");
view.Rotate(CoordAxis.COORD_AXIS_Y, 90.0);
currentModel.SaveView("RIGHT");
currentModel.RetrieveView("FRONT");
view.Rotate(CoordAxis.COORD_AXIS_X, 90.0);
currentModel.SaveView("TOP");
view.Rotate(CoordAxis.COORD_AXIS_X, 180.0);
currentModel.SaveView("BOTTOM");
currentModel.RetrieveView("FRONT");
view.Rotate(CoordAxis.COORD_AXIS_Z, 180.0);
view.Rotate(CoordAxis.COORD_AXIS_Y, 45.0);
view.Rotate(CoordAxis.COORD_AXIS_X, 35.0);
currentModel.SaveView("FRONT_RIGHT_BOTTOM_ISO");
currentModel.RetrieveView("FRONT");
view.Rotate(CoordAxis.COORD_AXIS_Z, 180.0);
view.Rotate(CoordAxis.COORD_AXIS_Y, -45.0);
view.Rotate(CoordAxis.COORD_AXIS_X, 35.0);
currentModel.SaveView("FRONT_LEFT_BOTTOM_ISO");
currentModel.RetrieveView("FRONT");
view.Rotate(CoordAxis.COORD_AXIS_Y, -45.0);
view.Rotate(CoordAxis.COORD_AXIS_X, 35.0);
currentModel.SaveView("FRONT_RIGHT_ISO");
currentModel.RetrieveView("FRONT");
view.Rotate(CoordAxis.COORD_AXIS_Y, 45.0);
view.Rotate(CoordAxis.COORD_AXIS_X, 35.0);
currentModel.SaveView("FRONT_LEFT_ISO");
currentModel.RetrieveView("REAR");
view.Rotate(CoordAxis.COORD_AXIS_Z, 180.0);
view.Rotate(CoordAxis.COORD_AXIS_Y, 45.0);
view.Rotate(CoordAxis.COORD_AXIS_X, 35.0);
currentModel.SaveView("REAR_RIGHT_BOTTOM_ISO");
currentModel.RetrieveView("REAR");
view.Rotate(CoordAxis.COORD_AXIS_Z, 180.0);
view.Rotate(CoordAxis.COORD_AXIS_Y, -45.0);
view.Rotate(CoordAxis.COORD_AXIS_X, 35.0);
currentModel.SaveView("REAR_LEFT_BOTTOM_ISO");
currentModel.RetrieveView("REAR");
view.Rotate(CoordAxis.COORD_AXIS_Y, -45.0);
view.Rotate(CoordAxis.COORD_AXIS_X, 35.0);
currentModel.SaveView("REAR_RIGHT_ISO");
currentModel.RetrieveView("REAR");
view.Rotate(CoordAxis.COORD_AXIS_Y, 45.0);
view.Rotate(CoordAxis.COORD_AXIS_X, 35.0);
currentModel.SaveView("REAR_LEFT_ISO");
currentModel.RetrieveView("FRONT");
session.GetModelWindow (currentModel).Repaint();

ModelItems items;
//Layer layer;
items = currentModel.ListItems(ModelItemType.ITEM_LAYER);
for(int i = 0; i < items.getarraysize(); i++) {
Layer layer = (Layer)items.get(i);
//items.get(i).GetName();
mesg = "layers to remove?" + layer.GetName();
//layer.xdelete();
DisplayMessage(mesg);
layer.Delete();
}

if(model.GetType().getValue() == ModelType._MDL_PART)
{
session.RunMacro("%layerp");
}
if(model.GetType().getValue() == ModelType._MDL_ASSEMBLY)
{
session.RunMacro("%layera");
}
//ModelItem params;
List<string> ParaRemove= Arrays.asList("DASH_NO", "MODELED_BY",
"MODELED_BY_DATE", "DWG_REV", "TITL3", "DESCRIPTION",
"FAMILY_TABLE_GENERIC", "PTNUM", "PTNAME", "VENDOR", "MFG", "MATL",
"USED_ON", "WEIGHT", "MATERIAL", "MATL_LIB", "THRD_SIZE_1", "NEXT_ASSY",
"BOM_DESC", "REV", "DESR", "ISSUED", "ISSUED_DATE", "PROD1", "NX1",
"PROD2", "NX2");
for(int i = 0; i < ParaRemove.size(); i++) {
try{
Parameter params = currentModel.GetParam(ParaRemove.get(i));
params.Delete();
}
catch (Exception e) {
App.writeLog("Problem removing item" +ParaRemove.get(i)+ ". "
+ e.toString());
//continue;

}
}
List<string> ParaDesignate= Arrays.asList("DESC",
"CHKR","CHK_DATE","DRAWN_BY","DRAWN_BY_DATE","RE","RE_DATE","TITLE1","TITLE2");
for(int i = 0; i < ParaDesignate.size(); i++) {
try{
Parameter params = currentModel.GetParam(ParaDesignate.get(i));
params.SetIsDesignated(true);
}
catch (Exception e) {
App.writeLog("Problem designating item"
+ParaDesignate.get(i)+ ". " + e.toString());
//continue;

}
}
List<string> ParaUndesignate= Arrays.asList("PTC_MATERIAL_NAME");
for(int i = 0; i < ParaUndesignate.size(); i++) {
try{
Parameter params = currentModel.GetParam(ParaUndesignate.get(i));
params.SetIsDesignated(false);
}
catch (Exception e) {
App.writeLog("Problem undesignating item"
+ParaUndesignate.get(i)+ ". " + e.toString());
//continue;

}
}
/*this is to remove unwanted parameters and designate wanted parameters
List<string> ParaDesignate= Arrays.asList("DESC",
"CHKR","CHK_DATE","DRAWN_BY","DRAWN_BY_DATE","RE","RE_DATE","TITLE1","TITLE2");


if(ParaDesignate.contains("the string you want to find"))
{
}
else{

}
String layers[] = <the list=" of=" layer=" names=">
For (int i=0, i<layers.length, i++)<br="/>
{
if (!layers[i].equals(“Hidden Items”)
{<delete the=" layer=">
}
}
ModelItems lays = mdl.ListItems(ModelItemType.ITEM_LAYER);
for (int j = 0; j < lays.getarraysize(); j++) {
System.out.println("delete " + ((Layer)lays.get(j)).GetName());
((Layer) lays.get(j)).Delete();
}*/
String[] args = null;
closeBOM();
}


// Inner class for UI Command Listener
//
public class WSFX_Btn1_CmdListener extends
DefaultUICommandActionListener {

// Handler for button push
//
public void OnCommand () {
try {
Btn1_callback();
}
catch (Exception e) {
writeLog("Exception thrown by Btn1_callback method: " +
e.toString());
}
}
}

/**
* Normalizes the transformation matrix. This is necesary to get
correct
* transformations
*
* @param t
* is a 3D transformation to normalize.
* @return the normalized 3D transform.
*/
private Transform3D normalize(Transform3D t)
{
try
{
Vector3D v = t.GetXAxis();
Matrix3D m3d = t.GetMatrix();
double scale = 1.0 / Math.sqrt(v.get(0) * v.get(0)
+ v.get(1) * v.get(1) + v.get(2) * v.get(2));
for (int i = 0; i < 3; i++)
{
m3d.set(3, i, 0.0);
for (int j = 0; j < 3; j++)
m3d.set(i, j, m3d.get(i, j) *
scale);
}
t.SetMatrix(m3d);
}
catch (Exception ex)
{
}
return t;
}

}
1-Visitor
March 20, 2012
We have Model check running to keep our quality up. However I found the
checking to be a little S%#$@y and regardless of warning or errors people
will not fix them unless I or another admin is behind them the whole way.
But model check is not too bad. we check for layers, parameters, units,
views out of place, formats yeah the whole shavang. its just not good
enough. I already investigated into automating some tasks and its possible.
But jlink and tool kit are so much better and versatile.

regards,

Alfonso



21-Topaz II
March 20, 2012
Layer rules are immensely powerful. You can fine tune what goes on
layers with rules. For example, my axis layer rules look for a feature
that has an axis that is not a mirror, mirrored merge, copy geom or
external copy geom. This creates a pretty clean set of part features
that contain an axis.



Another nice feature of layer rules is they can be extended from an
assembly down through the entire tree to all the components below. So,
you can add those axis rules above at the top level assy and then extend
them into hundreds of part below with a couple of clicks (select the
layer, click the 'layer' menu then 'extend rules'). This means that I
was able to create a single mapkey (actually several nested mapkeys)
that strip all layers from an assembly and all parts, create the top
level rule based layers and extend them to all parts. Now all layerable
items are on layers and I can add more layers to control smaller subsets
of geometry.



While that could be done with model check, layer rules update the layer
contents automatically as you work. That means the benefit of having
items on layers and being able to control what's visible is available to
you as you work and add features.



I learned all of this from Glenn Beer's 2007 presentation. I can't
stress enough how valuable it is, as Ben pointed out earlier, you can
find it and an info rich discussion here:



1-Visitor
March 20, 2012

I did a presentation on rules (mostly for layers) at the 2009 conference if anybody is interested it is attached.


Mark

1-Visitor
March 20, 2012

Some folks are having issues with link, not sure why. It is at bottom of email under "Attachment Links":


http://portal.ptcuser.org/p/fo/do/download=1&fid=14233

1-Visitor
March 20, 2012
YIKES!



This does sound powerful, but ugly in a PDMLink environment...



Intentionally touching checked out objects is fine- it's the unwanted
touches en mass as these rules are extended that may get messy...



Eric Slotty

- <">mailto:->

414-362-2552


1-Visitor
March 20, 2012
Actually as with anything in windchill you gotta keep track of what you
work on. This is more of a librarian script rather than an every day user
script.

I tell my users to "only modify what is on the CO" and to set everything
except for those items int he CO for read-only. That way they can modify
all they want, it will always give an error, not save or just warn them
that they are changing something that they should not change.

In windchill I think there is also such a thing. We use intralink at the
moment. the old one 3.4. In windchill/pdmlink/intralink its a little
different. I used rev 8, they probably made some upgrades through the past
two years.

regards,
Alfonso

On Tue, Mar 20, 2012 at 10:23 AM, Slotty, Eric (GE Healthcare) <
-> wrote:

> YIKES!****
>
> ** **
>
> This does sound powerful, but ugly in a PDMLink environment… ****
>
> ** **
>
> Intentionally touching checked out objects is fine- it's the unwanted
> touches en mass as these rules are extended that may get messy… ****
>
> ** **
>
> *Eric Slotty*
>
> -*
>
> *414-362-2552*
>
> ** **
>
> *From:* Doug Schaefer [
> which really means automatic. If you set it to automatic, then any new
> plane goes into the plane folder, and any new feature named for example
> "cool_feature_XX" could also be automagically pulled into a specific layer.
> ****
>
> ** **
>
> My start parts have their layers set to hidden by default. For any older
> part or badly imported OTS part I made a map key to create the layers and
> set them up with the rules. But then this took a few too many seconds. So I
> wrote a Jlink up to not only fix the layers but also create views and check
> parameters and remove un used ones. The jlink version runs probably 20 to
> 50 times faster. Setting rules tends to be the slow part. The views are
> created in the blink of an eye and same for parameter checking.****
>
> ** **
>
> My next step is to make this a batch script and just fix everything once
> and for all. I'm tired of opening a part and having to click a thousand
> times to get rid of the mess of planes and lines and points and coordinate
> systems and notes and surfaces and the kitchen sink. Just tired of it.
> Maybe I'll post a write up. I'll post the source code in a few. Its a
> modification of some other jlink stuff I found on the internets.****
>
> ** **
>
> regards,****
>
> ** **
>
> Alfonso****
>
> ** **
>
> ** **
>
> On Mon, Mar 19, 2012 at 8:50 AM, Chris Gosnell <->
> wrote:****
>
> Thanks for the info. I always wondered why I'd want to use isolated, I'll
> have to check this out.****
>
> ****
>
> And mentioning again, you can use Modelcheck to check/change the layer
> visibility preferences to suit your standard.****
>
> ****
>
> Christopher F. Gosnell****
>
> ****
>
> FPD Company****
>
> 124 Hidden Valley Road****
>
> McMurray, PA 15317****
>
> PH:724.941-5540****
>
> FX:724.941.8322****
>
> www.fpdcompany.com****
>
>
1-Visitor
March 21, 2012
I created the attached diagrams** as an aid to map out where everything
was. From Mark Ganzer's (Thanks) presentation, I now know what the
'extend layers' item is for.

The layers I usually use are mostly functional, not by geometry type.
Why bother automatically putting curves on a curves layer? When I want
to do some such I can just search and get them.

Instead, I have layers, e.g. an always hidden set_datums layer, ruled to
automatically put shown datums (PTC, is anyone in charge of
consistency?) and another rule that removes shown datums from the datums
layer. Then there is Construction, for geometry used in constructing
other geometry - also usually hidden and not automatic.
Drawing_enhancement for curves and such that make the drawing easier to
deal with (intersection extensions where dimensions originate.

That sort of thing - to record, for the most part, what the items are
for, not the geometry type of the geometry that is on them.

I would like to have the drawing layers really work the right way. If I
have an assembly drawing and I turn off the Construction layer on the
drawing, add a new component to the assembly, and come back to the
drawing, the Construction layer is off for all components except the one
just added. Likewise, if someone decides to set a datum, it also filters
up and has to be turned off, drawing by drawing, level by level. Am I
somehow missing a setting that will continuously update the drawing with
the drawing layer selections?

I've also noticed, but not much used, the ability for assemblies to
contain layers and visibility settings for geometry that is not part of
the assembly - so that I could have an assembly shut off all the
component shown datums, even if the part creators did not.

Fun topic. Nice PowerPoint.


Dave S.

**Created using DIA, hence the text searchable PDF.