Community Tip - Stay updated on what is happening on the PTC Community by subscribing to PTC Community Announcements. X
How do you create a component interface to Geometry feature that allow for automatic assembly (autoplace) of a component to an assembly based on a named coordinate system. We figured out how to do similar using the Interface to Interface capabilities, however that requires defining an interface in EVERY receiving assembly. We would like to do this WITHOUT adding an interface feature in every assembly.
E.g. Align a nut to an assembly purely based off a named coordinate system using query rules defined in the component interface?
We are using Creo4, however will be moving to Creo7 soon.
Solved! Go to Solution.
Thank you to everyone who helped on this. We found a combination of methods that is working exactly how we want and am posting here as the solution and perhaps it will help someone else. It is necessarily lengthy as I wanted to give the complete solution that I asked for in the original post and perhaps help someone else too.
@pausob, Thank you for your last solution. Although when I first saw it I dreaded the idea of creating and dreaded even more maintaining it, I realized that if I used a saved Query instead of mapkeying the query it will be shorter mapkeys, more stable, and easier to maintain/troubleshoot. We can now auto assemble a sub-assembly entirely except just the one surface we cannot define automatically but the user can then easily pick that surface to finish the full definition of assembly constraints.
I ended up using a combination of tools:
Method:
Example Mapkeys (generalized for posting her):
Example Interface to Geometry footer feature inside the placing component sub-asm:
Example of a retrieved search query:
It is possible to enable automatic assembly using declared datums in a Notebook. No query rules or interface definitions are required to implement this using a Notebook.
Refer to this article for details and links to example models:
https://www.ptc.com/en/support/article/CS234134
@tbraxton, I work with Dayal who posted this. We have never used notebooks for anything and are totally unfamiliar with them so will have to look into them some more. If you have any good material on using them please post if you have a moment.
This method worked for me:
1) define the interface in your component and attach a query to it:
2) upon assembling of this component, set it for multiple placement:
->
Select the interface and click "Multiple" button.
3) Click on the Auto Place button:
4) In the Auto Place dialog box, define the search scope (screen point method did not work for me, but selecting the top level assembly as the item did), then "Find Now", then click in the locations found list, Ctrl+A to select all, click ">>" button to transfer to the selected list:
5) Close the Auto Place dialog box, click the green check-mark and it is done:
System auto-placed the fitting according to the criteria that the mating coordinate system is named PORT*
Note: I needed to change few settings in the "Assembly" section of the Creo Parametric Options for the above dialog boxes and the "Auto Place" button to show up during the assembly process:
@pausob, To be clear, the method you are describing is for Interface to Geometry, not interface to interface, right?
Hi @LawrenceS, I would say I showed a component with an interface being "semi-automatically" assembled to geometry in multiple places 😄. Maybe with a clever mapkey it could become a 1-button operation.
Hi @DP_9634838,
Please see the attached video for more information. Hope this helps.
Thanks,
Vipul
@VipulT, Thank you very much for the video and explanation, as we have it working almost perfectly.
After further testing we have run into a problem where it is trying to assemble to coordinate systems within other sub-components. As far as we can tell, the multiple locations autoplace doesn't distinguish between datums within sub-components and top-level datums, nor could we figure out how to specify this in the placing component Interface feature.
How do we specify to only use the named coordinates in the top-level assembly?
PS.
We already tried using the below methods and they don't seem to work on Creo4 (M140 and M150):
However, for this new process to work we really need to choose top level assembly references/coordinate system only. Any ideas?
How about activate Insert mode and do the above procedure before any other sub-component is present in your assembly? That way only the top-level assembly datums will be "found"...
So you do want to reference the sub-component geometry? but only 1-level deep? Anyway, it seems that auto-place tool doesn't give you many options as far as filtering that list of found locations, so seems you should raise a product enhancement idea...
Also, this thread:
Auto assemble multiple components by coordinate in selecting multiple coordinates in top assembly
has links to other softwares that you may want to evaluate to see if they fulfill your needs.
Using the Notebook to control auto assembly this could solve this issue. The automatic assembly would only happen if the Notebook is declared to a model. You can declare/undeclare the Notebook used to each model as required.
I have been trying to understand how these Notebooks/Layouts work and it is very interesting functionality. Thanks again for sharing it.
Please correct me if I am wrong, but using Notebooks requires the receiving asm/prt to have a Notebook definition tied to it. In the case we have, we have many thousands of unique receiving assemblies. In addition, we don't have a common part that could have a notebook tied to it either. It seems we would require a Notebook for every receiving assembly, or a notebook for every component it could be tied to, which both would be a more painful solution to create/maintain than what it alleviates.
Do I understand this correctly, or is there a way around this?
You must create a Notebook that defines the assembly constraints for the two models to be automatically assembled. You must declare this notebook to the two models.
If you are familiar with programming structure, think of a Notebook as a declaration of global variables and functions that can be accessed by other programs (models) when declared to the model.
Without understanding exactly how you are auto assembling I can not comment on how many Notebook files would be required. If you are clever about standardizing the assembly references in the models you should be able use a single notebook to assemble parts infinitely.
I assume you have parts that you reuse often, if so you can create a standard such that the part would auto assemble to any assembly designed to receive it once you declare the Notebook used to define the constraints to the receiving model and your library part designed for auto placement.
I present it as an option for auto assembly, it may be better than a query approach. If you post a sample data set representative of the issue then I would be able to consider what would work.
I don't have anything I can share in this forum. When I get some time I will create a simple example. What version of Creo are you working in currently?
THanks @tbraxton, We are using Creo4 and planning on Creo7 in the next couple of months.
@pausob, DayalP's comment on your clever workaround to suppress all components in assembly before assembling, must seem like a contradiction to our original question. We posted on a simplified version of what we really want using only a coordinate system, as it is easier to explain and if we can get that to work then we can get the slightly more complex version to work. We are actually assembling based on 3 consistently named datums/axis, then we remove one of the assembly constraints to allow for the user to choose an assembly surface that there is not defined as special in the actual model. We automate this using a mapkey, so the user only clicks the mapkey, chooses the unique surface and the component is fully assembled. We could have the mapkey suppress/insert mode but then the next part of the mapkey where the user chooses the surface wouldn't be possible. We will look into a method of suppressing/un-suppressing while assembling but think it will complicate the mapkey tremendously.
That is the background on why I don't think the suppressing workaround will work in this case, however the original question of using a query to define in the component how that component will get assembled in the top level assembly still holds. I didn't anticipate that it would be hard for Creo to query only top-level datums, as that is actually a normal query feature. In addition, for some reason the config.pro option and the Creo assembly option doesn't seem to be working, which would allow for us to specify to only look at the top level assembly. It seems that this functionality is broken. We will also see how it works in Creo7...
As it is, I'm guessing you are auto-assembling (a single component ?) using an interface to consistently-named datum geom, then replacing one of the constraints to be aligned with some surface of interest found in current context. That whole process seems challenging to encode into a mapkey without pauses, etc..., so I'd be quite interested to know how you accomplish that. Would you be able to share a model / mapkey example?
And during this process, the system presents you with unwanted locations because it finds same-named datums in other sub-components?
So is the sticking point is having users specify one of several locations that come up in the auto-place function?
I can think of two other things:
1) maybe you can do this whole thing by simply incorporating search queries in your mapkey at the time of standard placement process. The placement surface is clicked and then mapkey is run. It brings in the component and aligns an internal named datum to the pre-selected surface. The other two constraints are done by searching for the named datums - this can be done "in top level" only...
2) note that you can give names to surfaces so I am thinking of another approach: create the placement surface in the top-level assembly (i.e. copy it from the sub-component), and name it something that matches the query criteria in your hardware component. This can be done in a mapkey as you can look for that surface by the "last" feature made. Though the name you give it will be static... Yeah, I think mapkeys are not very good here; this definitely seems like an abuse of their limited powers - whole lot of extra work, and you make 1 extra feature in the model tree.
Anyway, happy hacking!
@pausob, we are actually auto assembling based on the multi-place but then only choosing the first location, and there is not even a manual way that I can tell that identifies which reference each location is tied to until we place the component and edit the references. That is the problem.
Dayal & I would be happy to demo this method for you, but right now it only exists on his computer, so please PM Dayal for a meeting.
I was able to create a mapkey without any pauses. The only problem is that it chooses the first location which appears somewhat random. It works about 80-90% of the time though because almost every component and sub-assembly are mostly axially symmetrically constrained (like a nut to bolt). The basic methodology is outlined below.
0) MODEL CONSISTENCY: We have consistently named datum type features in ~99% of all pertinent models
1) CONFIG.PRO: These are his specialized Config.pro settings:
2) INTERFACE: The interface is defined in the placing component e.g. ComponentA.asm
3) MAPKEY: This is an example mapkey of how we are doing it, and we have about 5 of these for (e.g. ComponentA-E):
mapkey ER08 @MAPKEY_NAMEAssemble ComponentA.asm;@MAPKEY_LABELComponentA.asm;\
mapkey(continued) ~ Command `ProCmdCompAssem` ;\
mapkey(continued) ~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` `file_open`;\
mapkey(continued) ~ Trail `UI Desktop` `UI Desktop` `PREVIEW_POPUP_TIMER` \
mapkey(continued) `file_open:Ph_list.Filelist:<NULL>`;\
mapkey(continued) ~ Input `file_open` `Inputname` `componentA.asm`;\
mapkey(continued) ~ Activate `file_open` `Inputname`;\
mapkey(continued) ~ Select `selintrfc` `IntrfcList` 1 `INTC6695`;\
mapkey(continued) ~ Activate `selintrfc` `MultiBtn`;\
mapkey(continued) ~ Activate `main_dlg_cur` `maindashInst0.AutoPlaceBtn`;\
mapkey(continued) ~ Select `autoplace_odui` `SearchTypeRadio` 1 `SearchScope`;\
mapkey(continued) ~ Select `main_dlg_cur` `PHTLeft.AssyTree` 1 `node0`;\
mapkey(continued) ~ Activate `autoplace_odui` `ExecutePB`;\
mapkey(continued) ~ Activate `autoplace_odui` `MoveToPlaced`;\
mapkey(continued) ~ Activate `autoplace_odui` `ClosePB`;%SectionAsm;
Hacking. Too funny. Creo and WC 'hacking' seems to be my specialty. 🤣
Hi @LawrenceS
I attached a toy example (Creo4 assembly) for you to try.
It shows how a component (test_bit.prt) can be assembled by selecting a datum plane or planar surface in the assembly context then pressing F12 to launch the mapkey.
The initial selection specifies the "orientation" and then mapkey searches for named datums in the component and in the top-level assembly to build the other two constraints.
I simply recorded the mapkey, so it must have a lot of extra baggage, but seems to work.
I think this shows that this can be done, but several things must be in place for it to work - for example, having those "temporary interfaces" or multiple auto-placement options active will break it as it will alter the "basic assembly workflow".
Also as with most mapkeys, that involve clicking through bunch of dialog boxes (including the notorious Search Results) it is probably super fragile.
Good luck!
Settings:
comp_assemble_with_interface NONE
create_temp_interfaces NO
Mapkey code:
mapkey $F12 @MAPKEY_NAMESTANDARD PLACEMENT WITH ORIENTATION DEFINED BY \
mapkey(continued) PRESENT SELECTION;@MAPKEY_LABELAUTOPLACE;~ Command `ProCmdCompAssem` ;\
mapkey(continued) ~ Trail `UI Desktop` `UI Desktop` `DLG_PREVIEW_POST` `file_open`;\
mapkey(continued) ~ Select `file_open` `Ph_list.Filelist` 1 `test_bit.prt`;\
mapkey(continued) ~ Command `ProFileSelPushOpen_Standard@context_dlg_open_cmd` ;\
mapkey(continued) ~ Activate `main_dlg_cur` `chkbn.ScrLayout.0` 1;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s0` `0`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s0` ``;\
mapkey(continued) ~ Command `ProCmdMdlTreeSearch` ;\
mapkey(continued) ~ Input `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Input `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Update `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Update `selspecdlg0` `ExtRulesLayout.ExtBasicNameLayout.BasicNameList` \
mapkey(continued) `COMP_PLANE_FOR_ORIENT`;~ Activate `selspecdlg0` `EvaluateBtn`;\
mapkey(continued) ~ Activate `selspecdlg0` `ApplyBtn`;~ Activate `selspecdlg0` `CancelButton`;\
mapkey(continued) ~ Open `ScrLayout.0.0` `PH.pop_constr_offset_type`;\
mapkey(continued) ~ Close `ScrLayout.0.0` `PH.pop_constr_offset_type`;\
mapkey(continued) ~ Select `ScrLayout.0.0` `PH.pop_constr_offset_type` 1 `Oriented`;\
mapkey(continued) ~ Activate `ScrLayout.0.0` `PH.L.PIM_Addpb.l0` 1;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s1` `0`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s1` ``;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s1` `0`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s1` ``;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s1` `0`;\
mapkey(continued) ~ Focus `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s1`;\
mapkey(continued) ~ Select `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s1` 0;\
mapkey(continued) ~ Command `ProCmdMdlTreeSearch` ;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s1` ``;\
mapkey(continued) ~ Input `selspecdlg0` `SelOptionRadio` `Axis`;\
mapkey(continued) ~ Input `selspecdlg0` `SelOptionRadio` `Axis`;\
mapkey(continued) ~ Update `selspecdlg0` `SelOptionRadio` `Axis`;\
mapkey(continued) ~ Update `selspecdlg0` `ExtRulesLayout.ExtBasicNameLayout.BasicNameList` \
mapkey(continued) `COMP_AXIS_FOR_PLACEMENT`;~ Activate `selspecdlg0` `EvaluateBtn`;\
mapkey(continued) ~ Activate `selspecdlg0` `ApplyBtn`;~ Activate `selspecdlg0` `CancelButton`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s1` `0`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s1` ``;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s1` `0`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s1` ``;\
mapkey(continued) ~ Command `ProCmdMdlTreeSearch` ;\
mapkey(continued) ~ Update `selspecdlg0` `ExtRulesLayout.ExtBasicNameLayout.BasicNameList` \
mapkey(continued) `AXIS_FOR_PLACEMENT`;~ Activate `selspecdlg0` `EvaluateBtn`;\
mapkey(continued) ~ Activate `selspecdlg0` `ApplyBtn`;~ Activate `selspecdlg0` `CancelButton`;\
mapkey(continued) ~ Open `ScrLayout.0.0` `PH.pop_constr_offset_type`;\
mapkey(continued) ~ Close `ScrLayout.0.0` `PH.pop_constr_offset_type`;\
mapkey(continued) ~ Select `ScrLayout.0.0` `PH.pop_constr_offset_type` 1 `Coincident`;\
mapkey(continued) ~ Activate `ScrLayout.0.0` `PH.L.PIM_Addpb.l0` 0;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s2` `0`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s2` ``;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s2` `0`;\
mapkey(continued) ~ Focus `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s2`;\
mapkey(continued) ~ Select `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s2` 0;\
mapkey(continued) ~ Command `ProCmdMdlTreeSearch` ;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s2` ``;\
mapkey(continued) ~ Input `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Input `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Update `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Update `selspecdlg0` `ExtRulesLayout.ExtBasicNameLayout.BasicNameList` \
mapkey(continued) `COMP_PLANE_FOR_PLACEMENT`;~ Activate `selspecdlg0` `EvaluateBtn`;\
mapkey(continued) ~ Activate `selspecdlg0` `ApplyBtn`;~ Activate `selspecdlg0` `CancelButton`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s2` `0`;\
mapkey(continued) ~ Command `ProCmdMdlTreeSearch` ;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.assem_ref_represent.l0.s2` ``;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s2` `0`;\
mapkey(continued) ~ Trigger `ScrLayout.0.0` `PH.L.S.l0.comp_ref_represent.l0.s2` ``;\
mapkey(continued) ~ Input `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Input `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Update `selspecdlg0` `SelOptionRadio` `Datum Plane`;\
mapkey(continued) ~ Update `selspecdlg0` `ExtRulesLayout.ExtBasicNameLayout.BasicNameList` \
mapkey(continued) `PLANE_FOR_PLACEMENT`;~ Activate `selspecdlg0` `EvaluateBtn`;\
mapkey(continued) ~ Activate `selspecdlg0` `ApplyBtn`;~ Activate `selspecdlg0` `CancelButton`;\
mapkey(continued) ~ Open `ScrLayout.0.0` `PH.pop_constr_offset_type`;\
mapkey(continued) ~ Close `ScrLayout.0.0` `PH.pop_constr_offset_type`;\
mapkey(continued) ~ Select `ScrLayout.0.0` `PH.pop_constr_offset_type` 1 `Coincident`;\
mapkey(continued) ~ Activate `main_dlg_cur` `dashInst0.stdbtn_1`;
@pausob, thank you for doing this. Before I dive into it in Creo, I was not able to determine what approach you are taking using this mapkey and we have talked about a lot of approaches such as Interfaces (GEom vs Intc-Intc), Notebooks, Query, etc.
Can you summarize what method/approach you are using to do this?
Hi @LawrenceS , the approach is the basic component assembly process of specifying 3 constraints to fully define its placement. In general, the mapkey replays using the search function to identify the named references in the incoming component (e.g. COMP_AXIS_FOR_PLACEMENT) and named reference in the (top level) assembly (e.g. AXIS_FOR_PLACEMENT). The exception is the first assembly reference which is specified by having it selected at the time of launching the mapkey...
You have mentioend some good suggestions, both of which we have discussed internally at length. This is what we have concluded:
We are also walking through the Notebook method that @tbraxton mentioned a few times in this thread in order to see if that gets us a little further than we currently have (and to open our eyes to new methodologies).
Thank you to everyone who helped on this. We found a combination of methods that is working exactly how we want and am posting here as the solution and perhaps it will help someone else. It is necessarily lengthy as I wanted to give the complete solution that I asked for in the original post and perhaps help someone else too.
@pausob, Thank you for your last solution. Although when I first saw it I dreaded the idea of creating and dreaded even more maintaining it, I realized that if I used a saved Query instead of mapkeying the query it will be shorter mapkeys, more stable, and easier to maintain/troubleshoot. We can now auto assemble a sub-assembly entirely except just the one surface we cannot define automatically but the user can then easily pick that surface to finish the full definition of assembly constraints.
I ended up using a combination of tools:
Method:
Example Mapkeys (generalized for posting her):
Example Interface to Geometry footer feature inside the placing component sub-asm:
Example of a retrieved search query: