- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
duplicate sheet and go to next member in base file using ilogic
Hello
I have an ipt file with model states, I created a drawing sheet for one model state, using iLogic, I need to duplicate the drawing sheet and replace the base model with the next model state until i finish the 300 models.
while creating the new sheet I need to rename the sheet according to the model partnumber.
Thanx alot
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi @raymaster. Have you ever used SheetFormats? You could create (Link, Link) a SheetFormat object from the existing sheet with the model view already in it. Then use Sheets.AddUsingSheetFormat to create each new sheet, and specify the 'model' you want to be in the view(s) on that new sheet. Also, if the view is already referencing the correct model file, but wrong ModelState within that file, then we can change which ModelState the view is referencing using its DrawingView.SetActiveModelState method.
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
yes I can do it manually, but it will be a monkey work for 300 pages.
thats why I tried to do it through iLogic, as the projects I do consist of more than 200 unit for a floor in 50+ floors' buildings, as for each unit I may have like 6 repetitive parts in different dimensions and model states.
so that I need this process automated.
Thanx
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi @raymaster. What I was suggesting was also all code automation, to add to your existing code, to accomplish the added functionality you were looking for. You said you already have some iLogic code in which you created a drawing sheet for a model with ModelStates, and want to duplicate that sheet for other ModelState versions of that model, and many other models. I believe that one way you could accomplish that is by creating/using SheetFormats, but by code. The links I included were for the Inventor API objects and methods involved in creating a new SheetFormat API object, and how to use that SheetFormat to create the next sheet in your drawing. That method includes supplying a new name for the new sheet, and supplying either a Document object or (FullFileName or FullDocumentName) for 'the model' you want to be represented in the views of the new sheet, and other settings. However, when reviewing the available settings for the method that creates a new sheet based on a SheetFormat, I did not see a specific setting for specifying ModelState. If the supplied Document object was already set to the ModelState you want, that might work...or, you could also ensure that the FullDocumentName you supply includes that name of the ModelState at its end (FullDocumentName = FullFileName & "<ModelStateName>"). If you do not, or can not specify the ModelState in one of those two ways, then I mentioned a way that you can change which ModelState an individual DrawingView is set to by code. This is all just one possible code process plan at this point. If you think this sounds like a direction you would like to go with your project, then maybe we could help you further develop your existing code in this direction. The alternative code process would be a bit more granular, creating each new sheet using the regular Sheets.Add() method, then creating each individual view on the new sheet using one of the available DrawingViews.Add type methods. Using the SheetFormat route just seems a bit simpler, because the SheetFormat already knows the sheet size, orientation, Border, TitleBlock, certain settings, and already includes the views, which the reference model for can easily be changed right when creating the sheet.
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
thanks @WCrihfield this is exactly what I was looking for, but I could not find the right API object to change the "model state" within the base "view".
the functions I look for:
1. duplicate the current sheet
2. change the "model state" within the existing "view"
3. update the name of the sheet upon the partnumber like so:
Dim drwDoc As Inventor.DrawingDocument = ThisDrawing.Document Dim drwSht As Inventor.Sheet For Each drwSht In drwDoc.Sheets Dim dRef As Inventor.Document = drwSht.DrawingViews.Item(1).ReferencedDocumentDescriptor.ReferencedDocument Dim pNum As String = dRef.PropertySets.Item(3).Item( "part number").Value drwSht.Name = pNum Next
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
OK. Those first two steps listed can definitely be tricky.
There is a Sheet.CopyTo() method, which sounds like it should be the right one to use, but it can only be used to copy the sheet to another drawing document, not for copying the sheet within the same drawing document. It says so right in its online documentation. That is why I assumed that the only other two options for copying the sheet are to create a SheetFormat based on the existing sheet (even if just a temporary one, that we can delete again later), then use that SheetFormat we just created to create a new sheet exactly the same as the existing one. Otherwise we would have to create the next sheet the longer way. The thought does come to mind to use a second, temporary drawing document, copy the sheet to it, then copy it back to the original drawing, but I do not recall if I have tried that idea before, and it may require a bit more system resources/processing/memory.
The DrawingView object has a property named ActiveModelState, which may seem like the way to go, but the problem is that it is a ReadOnly property. So we can check it, but cant change its value directly. However, the DrawingView object also has a method (DrawingView.SetActiveModelState) just for setting its value, which also has a couple other optional setting you can specify, such as if you want to update any PartsList that may be based on that view, and if you want to keep any overrides. I do not know exactly why it is set-up that way, only that this is the way it must be done. Also, I think this method may only work on 'Base Views', and may not work on other types of view like projected, because they are controlled by the view they are projected from. It also says that this method will fail if the reference to the model is 'unresolved'. It does seem like I may have heard of some awkward behavior in this area though, but I can not remember the details, since I do not do a lot of in-depth drawing side automation where I work.
If I get a chance later, I may attempt to create some code for this task, test it, and get back with you. I've got to deal with some other stuff at the moment though. Sometimes I spread myself too thin across multiple projects (multi-tasking).
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Sorry to hijack your post @raymaster
I was facing a similar issue, but the suggestion of @WCrihfield got me to a working result. The next issue I'm facing is that this method is not copying dimensions that are already placed on the first sheet
If that could also be done, it would be perfect.
It takes an .idw and uses the single sheet present as a temporary sheetformat. Then it steps through the model states and creates new sheets with names equal to the model states and it changes the model state in the base view for each new sheet created. I also still have to figure out a clean way to skip the [Primary] model state.
EDIT: a simple solution to skip the Primary model state is to start counting at 2 at line 27
' iLogic Rule: Duplicate Sheets for Model States
' This rule duplicates an existing sheet for each model state in the referenced part/assembly,
' updates the base view to match the corresponding model state, and renames the sheet.
' Get the active document (assumes it is a .idw file)
Dim oDrawingDoc As DrawingDocument = ThisApplication.ActiveDocument
' Get the first sheet (this will serve as the template for duplication)
Dim oTemplateSheet As Sheet = oDrawingDoc.Sheets.Item(1)
Dim oSheetFormats As SheetFormats = oDrawingDoc.SheetFormats
Dim oTempSheetFormat As SheetFormat = oSheetFormats.Add(oTemplateSheet,"Geo-IT Temp SheetFormat")
' Get the referenced model from the base view on the template sheet
Dim oBaseView As DrawingView = oTemplateSheet.DrawingViews.Item(1)
Dim oReferencedModel As Document = oBaseView.ReferencedDocumentDescriptor.ReferencedDocument
' Get the model states from the referenced model
Dim oModelStates As ModelStates = oReferencedModel.ComponentDefinition.ModelStates
' Ensure the model states collection is not empty
If oModelStates.Count = 0 Then
MessageBox.Show("No model states found in the referenced model.", "Error")
Return
End If
' Loop through the model states and create a sheet for each
For i As Integer = 1 To oModelStates.Count
Dim oModelState As ModelState = oModelStates.Item(i)
' Create a new sheet by duplicating the template sheet, reference the model and change the name
Dim oNewSheet As Sheet = oDrawingDoc.Sheets.AddUsingSheetFormat(oTempSheetFormat,oReferencedModel,oModelState.Name)
' Update the base view on the new sheet to reference the corresponding model state
Dim oNewBaseView As DrawingView = oNewSheet.DrawingViews.Item(1)
oNewBaseView.SetActiveModelState(oModelState.Name)
Next
'Remove the temp sheet format
oTempSheetFormat.Delete()
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
There is actually another way to do this which will preserve all your dimensions and such. I'm not sure why I did not mention this in any of my earlier posts here. It seems like I have shown this method in a few other places in the forum before. Anyways, it uses the basic Copy/Paste system, combined with simulating some user inter face actions, such as selecting the active sheet, executing a command (copy), unselecting that sheet, then executing another command (paste). It includes some Inventor API code, but is a mix of using API and simulating user interface actions, so it will only work when that drawing is currently the 'active' document (currently fully visible on your screen at that moment). I even took it another step further and turned it into a separate Function routine, which will then retrieve and return the newly created copy of the active sheet for you. It is still not 'perfect', but pretty close. Of course it could still be developed further, such as adding the option to rename the new sheet, and/or repositioning the new sheet to a specific location, instead of just at the end of all existing sheets. As it is right now, the name of the new sheet will always start with "Copy of ", then the name of the original sheet, but with the new index number at the very end, because we can not control that index number. Also, if the active sheet (when you run the rule) contains views which have 'parent' views on another sheet, then it will show a small dialog telling you that the parent view must be copied along with the child view, due to the child view being dependent on the parent view, with only an OK button, so it will not copy that sheet.
Below is that code example:
Sub Main
Dim oInvApp As Inventor.Application = ThisApplication
Dim oDDoc As DrawingDocument = TryCast(oInvApp.ActiveDocument, DrawingDocument)
If oDDoc Is Nothing Then Return
Dim oSheet As Inventor.Sheet = oDDoc.ActiveSheet
Dim oNewCopySheet As Inventor.Sheet = CopySheet(oSheet)
Logger.Info("New Sheet's Name = " & oNewCopySheet.Name)
End Sub
Function CopySheet(oSheet As Inventor.Sheet) As Inventor.Sheet
If oSheet Is Nothing Then Return Nothing
Dim oDDoc As DrawingDocument = oSheet.Parent
Dim oInvApp As Inventor.Application = oSheet.Application
If oDDoc.Views.Count = 0 OrElse oDDoc IsNot oInvApp.ActiveDocument Then
Try 'it must be the 'active' document (visibly showing on your screen)
oDDoc = oInvApp.Documents.Open(oDDoc.FullDocumentName, True)
oDDoc.Activate()
Catch : End Try
End If
Dim oCmdMgr As CommandManager = oInvApp.CommandManager
Dim oCDs As ControlDefinitions = oCmdMgr.ControlDefinitions
oCmdMgr.DoSelect(oSheet)
oCDs.Item("AppCopyCmd").Execute()
oCmdMgr.DoUnSelect(oSheet)
oCDs.Item("AppPasteCmd").Execute()
Dim oNewSheet As Inventor.Sheet = oDDoc.Sheets.Item(oDDoc.Sheets.Count)
Return oNewSheet
End Function
One possible further developed version of that custom Function might look something like this:
Sub Main
Dim oInvApp As Inventor.Application = ThisApplication
Dim oDDoc As DrawingDocument = TryCast(oInvApp.ActiveDocument, DrawingDocument)
If oDDoc Is Nothing Then Return
Dim oSheet As Inventor.Sheet = oDDoc.ActiveSheet
'<<< if just copying one sheet, expect one Sheet to get returned >>>
'Dim oNewSheet As Inventor.Sheet = CopySheet(oSheet, 1)
'Logger.Info("New Sheet's Name = " & oNewSheet.Name)
'OR
'<<< if creating multiple copies, expect an array of Sheet to be returned >>>
Dim oNewCopies() As Inventor.Sheet = CopySheet(oSheet, 2, "Sheet 3", "Sheet 4")
Logger.Info("New Sheet Names:")
For Each oNewCopy In oNewCopies
Logger.Info(oNewCopy.Name)
Next
End Sub
Function CopySheet(ByVal oSheet As Inventor.Sheet, _
iNumberOfCopies As Integer, _
ByVal ParamArray NewSheetNames() As String) As Object
If oSheet Is Nothing Then Return Nothing
If iNumberOfCopies < 1 Then Return Nothing
Dim bMultipleCopies As Boolean = (iNumberOfCopies > 1)
Dim bNamesProvided As Boolean = ((NewSheetNames IsNot Nothing) AndAlso (NewSheetNames.Length > 0))
Dim oDDoc As DrawingDocument = oSheet.Parent
Dim oInvApp As Inventor.Application = oSheet.Application
If oDDoc.Views.Count = 0 OrElse oDDoc IsNot oInvApp.ActiveDocument Then
Try 'it must be the 'active' document (visibly showing on your screen)
oDDoc = oInvApp.Documents.Open(oDDoc.FullDocumentName, True)
oDDoc.Activate()
Catch : End Try
End If
Dim oCmdMgr As CommandManager = oInvApp.CommandManager
Dim oCDs As ControlDefinitions = oCmdMgr.ControlDefinitions
Dim oCopyCmd As ControlDefinition = oCDs.Item("AppCopyCmd")
Dim oPasteCmd As ControlDefinition = oCDs.Item("AppPasteCmd")
Dim oNewSheet As Inventor.Sheet = Nothing
Dim oNewSheets As List(Of Inventor.Sheet)
If bMultipleCopies Then oNewSheets = New List(Of Inventor.Sheet) 'initialize it
For i As Integer = 1 To iNumberOfCopies
oCmdMgr.DoSelect(oSheet)
oCopyCmd.Execute()
oCmdMgr.DoUnSelect(oSheet)
oPasteCmd.Execute()
oNewSheet = oDDoc.Sheets.Item(oDDoc.Sheets.Count)
If bNamesProvided Then
Try
oNewSheet.Name = NewSheetNames(i - 1)
Catch e As Exception
Logger.Error(e.ToString)
End Try
End If
If bMultipleCopies Then oNewSheets.Add(oNewSheet)
Next
If bMultipleCopies Then Return oNewSheets.ToArray
Return oNewSheet
End Function
If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS)
.
Wesley Crihfield
(Not an Autodesk Employee)