Ilogic to display a thumbnail

Ilogic to display a thumbnail

dypro
Advocate Advocate
858 Views
9 Replies
Message 1 of 10

Ilogic to display a thumbnail

dypro
Advocate
Advocate

Hello everyone

I'm trying to create something that checks if all the parts of an assembly have the property description filled and if not I want it to show me a box to fill the description.
I have managed to do that, but I want to see a small image of the part in each box, because sometimes you don't know the item by name

I have been trying for a while, but I have not been able to to it.

Here is the code I have so far:

Sub Main()
    
    Dim oAsmDoc As AssemblyDocument
    oAsmDoc = ThisApplication.ActiveDocument

    
    For Each oOccurrence As ComponentOccurrence In oAsmDoc.ComponentDefinition.Occurrences
        
        Dim oPartDoc As PartDocument
        oPartDoc = oOccurrence.Definition.Document

        
        Dim oPropertySet As PropertySet
        oPropertySet = oPartDoc.PropertySets.Item("Design Tracking Properties")
        oProperty = oPropertySet.Item("Description")
			If oProperty.Value = ""
				oProperty.Value = InputBox("Introduce la descripción para el elemento", oPartDoc.DisplayName)
			Else
				MessageBox.Show(oProperty.Value,oPartDoc.DisplayName)
			End If	
        
    Next
End Sub
0 Likes
Accepted solutions (3)
859 Views
9 Replies
Replies (9)
Message 2 of 10

Mathias_CompC
Enthusiast
Enthusiast

TL;DR

I got a bit excited and wrote half a novel that is most likely out-of-scope.

 

 

I don't have exactly what you ask for(I do, but only by analog) but I do have what I consider a better solution. 

I, sort of, assume you are running either an add-in or a standalone here, but even if you are not I say you could modify it to work any way. I'm posting the relevant part of the header and the thread spinning the camera around a point. 

 

A simplification would be along the lines of,

InvApp.ActiveView.Camera.Eye , .Target, .Upvector

Followed by

.Apply()

 

If you actually want a thumbnail, the best way I've found is to save it instead of trying to access the stdole. (If you are running out of process that is)

    Public Sub SaveImage()
        _Cam.SaveAsBitmap("C:\TEMP\HI-curr.jpg", 600, 600)
        _Cam.SaveAsBitmap("C:\TEMP\curr.jpg", 200, 200)
    End Sub

This "obviously" requires a full implementation of a structure similar to mine, but that could also be done, "easily".

 

In-process(with add-in) I have the following

Dim cam As Inventor.Camera = g_inventorApplication.ActiveView.Camera
        cam.Fit()
        cam.ApplyWithoutTransition()
        Try
            Dim tclr As Inventor.Color = g_inventorApplication.TransientObjects.CreateColor(80, 80, 80)
            Dim bclr As Inventor.Color = g_inventorApplication.TransientObjects.CreateColor(140, 140, 140)
            g_inventorApplication.SilentOperation = True
            cam.SaveAsBitmap("C:\TEMP\HI-curr.jpg", 600, 600, tclr, bclr)
            cam.SaveAsBitmap("C:\TEMP\curr.jpg", 200, 200, tclr, bclr)
            g_inventorApplication.SilentOperation = False
        Catch ex As Exception
        End Try

        Try
            pctBox.ImageLocation = "C:\TEMP\curr.jpg"
            pctBox.Load()
            InvPartNr = g_inventorApplication.ActiveDocument.PropertySets.Item(3).Item(2).Value
            InvTitle = g_inventorApplication.ActiveDocument.PropertySets.Item(1).Item(1).Value
            FileName = g_inventorApplication.ActiveDocument.FullFileName
            InvRev = g_inventorApplication.ActiveDocument.PropertySets.Item(1).Item(7).Value
        Catch ex As Exception
            MessageBox.Show("Err 1: " & vbNewLine & ex.Message)
        End Try

 

The big out-of-process stuff as follows.

    Private _Cam As Inventor.Camera
    Private _Steps As Integer 'revolution resolution
    Private _CamDist As Integer 'Initial target distance
    Private _First As Boolean 'Transitioncontrol, set to TRUE when changing target
    Private _Target As Inventor.Point
    Private x As Double 'Cameraposition X
    Private y As Double 'Cameraposition Y
    Private z As Double 'Cameraposition Z

Private Sub Spin()
Dim _x As Double 'Angleparameter for target vector


        While True
            For i As Integer = 1 To _Steps
                _x = i / _Steps * (2 * Math.PI)

                x = _CamDist * Math.Cos(_x)
                z = _CamDist * Math.Sin(_x)

                _Cam.Eye = _invApp.TransientGeometry.CreatePoint _
                    (XCoord:=_Target.X + x, YCoord:=_Target.Y + y, ZCoord:=_Target.Z + z)
                _Cam.UpVector = _invApp.TransientGeometry.CreateUnitVector(0, 1, 0)
                _Cam.Target = _Target
                If _First = True Then
                    _Cam.Apply()
                    _First = False
                    Threading.Thread.Sleep(300)
                Else
                    _Cam.ApplyWithoutTransition()
                End If
            Next
            If _spinning = True Then

            End If
        End While
End Sub

 

The folowing is the creation of a new background spinnithingy

Public Sub New(ByVal inventorApp As Inventor.Application,
                   Optional ByVal Steps As Integer = 360,
                   Optional ByVal CamDistance As Integer = 100,
                   Optional ByVal CamHeight As Integer = 75)

        Snurr = New Threading.Thread(New Threading.ThreadStart(AddressOf Spin))
        _invApp = inventorApp
        _Cam = _invApp.ActiveView.Camera

        _Steps = Steps
        _CamDist = CamDistance
        _First = True
        y = CamHeight
    End Sub

 And when the prompt is about to happen I call the following(Yes, I do feel shame about the quad-indentation)

'Find occurrence midpoint
                Dim _tx = RefOcc.RangeBox.MaxPoint.X -
                    ((RefOcc.RangeBox.MaxPoint.X - RefOcc.RangeBox.MinPoint.X) / 2)
                Dim _ty = RefOcc.RangeBox.MaxPoint.Y -
                    ((RefOcc.RangeBox.MaxPoint.Y - RefOcc.RangeBox.MinPoint.Y) / 2)
                Dim _tz = RefOcc.RangeBox.MaxPoint.Z -
                    ((RefOcc.RangeBox.MaxPoint.Z - RefOcc.RangeBox.MinPoint.Z) / 2)
                Dim _target As Inventor.Point = _invApp.TransientGeometry.CreatePoint _
                    (_tx, _ty, _tz)
                Try
                    Spinner.NewTarget(_target)
                Catch ex As Exception
'exception handler
                    Spinner.NewTarget(origin)
                End Try

 

0 Likes
Message 3 of 10

dypro
Advocate
Advocate

Thanks for the answer @Mathias_CompC 

I have to confess that I did not understand even half of what you posted, I know very little ilogic, and what I learnt was by myself, I know enought to make some simple things I need, but not enought for advanced things. In those cases I just ask for help here to someone that knows more than me so he undestands what I want and manages to merge my badly written code with his code in orden to make it work, but i'm hopeless on understanding it half of the time.

I'm not using an add in , is just a ilogic file.

Then what I understood of all you posted is that is better to save the image and then call it back?
That would fill my pc with a lot of images that I only would use once wouldn't it?

If I where to try what you posted, I have to add a way to get the thumbnail of a piece of the assemby, save that image, then call that image with the box to insert the text I need, display those, fill the text i need to fill, then delete that image if possible and repeat it for each piece of the assembly. I have no idea of how to do such thing either...

 

PD: not sure about the spinny thing what is it for?

0 Likes
Message 4 of 10

Mathias_CompC
Enthusiast
Enthusiast

I was in the wrong to dump my solutions on you like that, I'm sorry. 

 

Would it fill your PC. No, It would overwrite the same file over and over.

If you write a program that works with Inventor via code-stuffs, that Standalone needs to reference everything quite explicitly. That's why the "full scope thing" is quite long and does alot, the "spinnything" makes the camera object in inventor revolve around the component you want to fill in properties for.

If you run with an Add-in you can do a lot more, a lot simpler. And if you run via iLogic, it's very simple, and you can do a little bit less. In your case, now that I know what scope we are working in, I'd actually suggest opening the file as an identification method.

ThisApplication.Documents.Open(docFile.FullFileName, True) 

 where docFile is your oPartDoc.

If you want, you can close it in a similar way.

Message 5 of 10

dypro
Advocate
Advocate

hi @Mathias_CompC 

Let's say I have an assembly with one hundred parts in it, some are ipts and some are iams.

What you suggest is that I add a line that opens the ipt or the iam, then the box to fill the description appears and then to save and close the file and repeat for every file that has not description isn't it?

It seems to be slower than what I have, but it might work...

I'm going to try and see if it works well.

I will keep you posted

0 Likes
Message 6 of 10

dypro
Advocate
Advocate

hi @Anonymous
It does work, as I feared it is a bit slow, but if I have nothing better I will use it.
Thanks for the help

0 Likes
Message 7 of 10

Mathias_CompC
Enthusiast
Enthusiast
Accepted solution

@dypro 

What is slow about it? 

How did you implement it?

Dim oAsmDoc As AssemblyDocument
    oAsmDoc = ThisApplication.ActiveDocument

For Each oOccurrence As ComponentOccurrence In oAsmDoc.ComponentDefinition.Occurrences
	     
	Dim oPartDoc As PartDocument
		oPartDoc = oOccurrence.Definition.Document
	Dim oPropertySet As PropertySet
		oPropertySet = oPartDoc.PropertySets.Item("Design Tracking Properties")
		oProperty = oPropertySet.Item("Description")
	If oPartDoc.PropertySets.Item(3).Item(14).Value <>"" Then
		Logger.Info("{0} had Desc: {1}", oPartDoc.DisplayName, oPartDoc.PropertySets.Item(3).Item(14).Value)
	Else
		Dim currDoc As Inventor.Document = ThisApplication.Documents.Open(oPartDoc.FullFileName, True)
			currDoc.PropertySets.Item(3).Item(14).Value = InputBox("Introduce la descripción para el elemento", oPartDoc.DisplayName)
			currDoc.Save()
			currDoc.Close(True)
			currDoc = Nothing		
	End If	
Next

 

Message 8 of 10

dypro
Advocate
Advocate
Accepted solution

hi @Mathias_CompC 
this is my code right now
for some reason either yours or mine crashes when there is an assembly

is there anyway to fix it?

it says you can't transform the COM object of ttype system._ComObject to the interface type "inventor.partdocument"

 

 

Sub Main()
    
    Dim oAsmDoc As AssemblyDocument
    oAsmDoc = ThisApplication.ActiveDocument

    
    For Each oOccurrence As ComponentOccurrence In oAsmDoc.ComponentDefinition.Occurrences
        
        Dim oPartDoc As PartDocument
        oPartDoc = oOccurrence.Definition.Document

        
        Dim oPropertySet As PropertySet
        oPropertySet = oPartDoc.PropertySets.Item("Design Tracking Properties")
        oProperty = oPropertySet.Item("Description")
			If oProperty.Value = ""
				ThisApplication.Documents.Open(oPartDoc.FullFileName, True) 
				ThisApplication.CommandManager.ControlDefinitions.Item("AppIsometricViewCmd").Execute
				oProperty.Value = InputBox("Introduce la descripción para el elemento", oPartDoc.DisplayName)
				ThisDoc.Save
				ThisApplication.ActiveDocument.Close (True)
			Else
				MessageBox.Show(oProperty.Value,oPartDoc.DisplayName)
			End If	
        
    Next
End Sub

 

 

 

0 Likes
Message 9 of 10

WCrihfield
Mentor
Mentor
Accepted solution

In lines 9 & 10, you are assuming that every component will be a part, not an assembly.  You may want to change that to a generic Document, instead of PartDocument, so it will work with either type.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 10 of 10

dypro
Advocate
Advocate

@Mathias_CompC @WCrihfield thank you both, it works

0 Likes