Macro per calcolare coordinate da schizzo 3D

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#41
Mi è venuta in mente un'idea (che probabilmente sarà una cavolata, ma te la espongo comunque): ho notato che SW ha un comando chiamato "Entità di divisione (Split entities)" che può suddividere una generica curva in tanti "pezzetti". Questi "pezzetti" sono delimitati ognuno da due punti (come ogni segmento): se io impostassi una funzione che interpellasse il comando "Split entities" e gli facessi capire in quante entità suddividere la mia curva (e quindi di conseguenza, in quanti punti) avrei risolto il mio problema.
Secondo te è una cosa fattibile?

Ciao e buone feste
 

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#42
Intanto che ci sono ti chiedo un parere su un'altra soluzione che mi è venuta in mente: partendo dalla macro che hai creato, dopo che essa ha identificato i vari tratti della curva, è possibile "unire" le varie entità in modo da crearne una unica e suddividerla in un certo numero di reference points tramite l'istruzione "swFeatMgr.InsertReferencePoint"?

Sarebbe per me una soluzione ottima e ti spiego il motivo: per il lavoro che devo fare sarebbe molto più comodo suddividere l'intera curva in un certo numero di punti, e non i singoli tratti, dal momento che vorrei dei punti equamente distribuiti lungo tutta la curva e non solo relativamente al singolo tratto (infatti se un tratto è lungo 10 mm e un altro è lungo 100 mm i punti non saranno alla stessa distanza fra loro lungo i due tratti, e questo è un grosso problema).


Grazie
 

jenuary

Utente Standard
Professione: Progettista e Programmatore VB.Net
Software: Solidworks
Regione: Veneto
#43
Da quanto capisco, a te serve suddividere una spline\poliline in parti uguali, non ricavare i punti di un profilo per passarlo ad un programma cam.
A questo punto buttiamo via tutto e ripartiamo, e per questo ti ho scritto una nuova macro sfruttando i RefPoint.

I prerequisiti sono:
- file di parte aperto con uno schizzo, lo schizzo non deve essere in modifica
- Lo schizzo si deve chiamare "Schizzo2", questo solo per il momento, perchè poi l'eventuale l'evoluzione della macro ci permettera di fare quello che vogliamo e selezionare uno dei tanti schizzi presenti nella nostra parte.
- lo schizzo2 deve contenere una spline (non piu di una mi raccomando, altrimenti bisogna inserire il controllo dell'errore)

Il risultato sarà:
- creazione di n punti di riferimento definiti dall'utente
- estrapolazione in Excel dei punti
- ripulitura del Feature Manager, cancellando i punti di riferimento.

L'evoluzione della macro a questo punto potra:
- scansionare lo schizzo e verificare se ci sono piu di un profilo aperto
- se il profilo è uno solo, ma non è una spline, trasforma il profilo in spline, cancellando le entità che l'anno generta.
- estrapolare i punti richiesti
- crearli fisicamente in un altro schizzo
- ecc.ecc.

Buon lavoro
 

Allegati

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#44
In effetti ciò che mi serve è una via di mezzo fra le due cose che hai descritto tu. A me serve una macro che, data una curva definita a tratti (un tratto di spline, uno di retta, uno di circonferenza, etc...) mi divida tutto il profilo in un certo numero di ref points. A questo punto le coordinate di questi ref points dovrei passare dentro un file txt.
Il file txt non finirà in un programma CAM, ma semplicemente verrà inviato al microcontrollore della fresa il quale penserà a convertire quei numeri in un linguaggio comprensibile dai motori.

Quindi la macro che mi hai appena scritto va bene (a parte che preferirei salvare in txt, ma questo non è un problema), ma funziona solo per una spline, invece io vorrei che funzionasse su una curva definita a tratti. Quindi secondo me ci vorrebbe una fusione delle due macro che mi hai scritto in questi giorni, in modo tale da:
- scansionare tutte le entità presenti nello schizzo e riconoscerle (retta, spline, arco, ...)
- dividere l'intera curva in un certo numero di ref points
- scriverne le coordinate in txt
- cancellare i punti

Dici che si possa fare una cosa del genere?


Ciao e grazie
 

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#45
Per farti capire meglio ti allego un'immagine di una curva di cui io vorrei ricavare le coordinate. E' costituita da 3 tratti: due tratti rettilinei e un tratto di spline.
Ciò che vorrei io è: dividere l'intera curva (non i singoli tratti) in un certo numero di ref points e calcolare le coordinate di questi punti. Una volta calcolate copiarle in un file txt. Infine cancellare i ref points.

Immagine.png
 

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#46
Ho trovato un comando che farebbe proprio al caso mio: "FIT SPLINE" (In italiano "Ottimizza Spline"). Praticamente questo comando, se si ha una curva definita a tratti, unisce tutte le entità creandone una unica sotto forma di una spline.
Il problema che non riesco a trovare nell' API il comando per richiamare l'istruzione fit spline. Se si riuscisse a fare funzionare questo comando da dentro la macro, a questo punto la macro che mi hai scritto qualche giorno fa andrebbe benissimo (ci sarebbe solo da salvare in txt e non in xls, ma penso non sia un problema).
Tu sai quale sia il codice per chiamare il comando "fit spline"?

Grazie
 

jenuary

Utente Standard
Professione: Progettista e Programmatore VB.Net
Software: Solidworks
Regione: Veneto
#47
Rieccomi...
Il problema principale è creare una polilinea dalle entità del tuo schizzo, ma è fattibile.
Ho fuso le due macro che ti avevo scritto, dove alla fine della scansione delle entità, creo una spline con tolleranza +-0.001, che successivamente vado a riselezionare dopo avere chiuso lo schizzo.
Il risultato è credo quello che ti serve...i punti per ora sono scritti in Excel, ma passarli al limite in txt non è un problema, l'abbiamo già fatto nelle prime bozze della macro.

Requisiti:
- File di parte con schizzo aperto, contente un solo profilo.

Risultato:
- estrapolazione dei punti della spline risultante, secondo la richiesta dell'utente.

A fine macro, se entri nel tuo schizzo e cancelli la spline, trovi sotto le tue curve originali in linea di costruzione.

Fammi sapere se ci siamo.

Ciao
 

Allegati

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#48
Innanzitutto grazie mille!!Ormai direi proprio che ci siamo.
Ho solo alcune curiosità da chiederti:

- la macro lavora anche con schizzi 3D? Perchè ho provato ma mi da alcuni errori
- quindi in pratica prima di avviare la macro io devo sempre crearmi una spline unica attraverso il comando "ottimizza spline"? Oppure posso semplicemente disegnare le mie entità e poi fare il run della macro senza dover ottimizzare la spline?


Ciao e grazie
 

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#49
Per la seconda domanda che ti ho scritto (quella relativa all'ottimizzazione della spline) mi sono già risposto da solo: non avevo notato che è la macro stessa a creare la spline partendo dalle varie entità!!:)
Mi rimane solo il dubbio del funzionamento o meno con schizzi 3D. Se funziona anche con quelli allora ci siamo, basta solo far si che salvi in txt e il gioco è fatto!

ciao
 

jenuary

Utente Standard
Professione: Progettista e Programmatore VB.Net
Software: Solidworks
Regione: Veneto
#50
In effetti non lavorava negli schizzi 3D, tutto dipendeva dalla stringa

Set Sketch = myPart.GetActiveSketch

la cui chiamata era obsoleta, ora l'ho cambiata in

Set Sketch = myPart.GetActiveSketch2

e gira bene anche con schizzi 3D, basta ora esportare in txt e sie a posto.

L'esportazione in txt è il caso che te la scriva tu, solo per il fatto che l'ordine di scrittura, gli spazi ecc., devono essere impostati secondo le tue esigenze, al limite se hai problemi fammi sapere.

Ciao e Buon Anno a tutti
 

Allegati

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#51
Perfetto!!A questo punto scriverò io l'esportazione in txt prendendo come spunto quella che mi avevi scritto in una precedente macro e poi la posterò su questa discussione!!
Nel frattempo ti ringrazio ancora e auguro a te e a tutti gli utenti del forum un buon 2014!!

Ciao
 

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#52
Mi permetto di chiederti un ultimo consiglio, dato che ormai siamo alla fine del lavoro: ho provato a scrivere il pezzo di macro per salvare in .txt ma, pur non avendo problemi in fase di compilazione, non scrive correttamente sul file di testo le coordinate.
Il risultato è che mi crea i ref points, mi crea il file di testo e mi cancella successivamente i ref points (quindi in teoria tutto perfetto). Il problema è che il file di testo è composto da soli valori "zero": in pratica ho un file txt pieno di zeri (tante colonne di zeri quanti sono i ref points).
Ti posto il codice che ho scritto, magari ho fatto un errore banale di cui non mi accorgo dato che non son pratico del VBA.

Codice:
    Dim swApp                                  As SldWorks.SldWorks
    Dim swModel                                As SldWorks.ModelDoc2
    Dim swFeat                                  As SldWorks.Feature
    Dim swSelMgr                               As SldWorks.SelectionMgr
    Dim swSubFeat                             As SldWorks.Feature
    Dim swSketch                               As SldWorks.Sketch
    Dim swSkPt                                  As SketchPoint
    Dim sFeatType                              As String
    Dim swRefPt                                 As SldWorks.RefPoint
    Dim swRefPtData                           As SldWorks.RefPointFeatureData
    Dim swRefPointFeatData                 As SldWorks.RefPointFeatureData
    Dim swMathPt                                As Variant
    Dim vswRefPt                                As SldWorks.RefPoint
    Dim swMgr                                    As SketchManager
    Dim vFeat                                     As Variant
    Dim v                                           As Variant
    Dim i                                            As Integer
    Dim j                                            As Long
    Dim sFilename As String
    Dim tFilename As String
    Dim f As Object
    Dim fs As Object
    Dim bRet                                    As Boolean
    Dim boolstatus As Boolean
    Dim longstatus As Long, longwarnings As Long
    Dim nLength                         As Double
    Dim xValue() As Double
    Dim yValue() As Double
    Dim zValue() As Double
    Dim point_count As Integer

...
...
...


'scansione del Feature Manager, se trovo punti di riferimento li scrivo nel file .txt
    Set swFeat = swModel.FirstFeature
    i = 1
    Do While Not swFeat Is Nothing
        sFeatType = swFeat.GetTypeName
         
            Select Case sFeatType
                Case "RefPoint"
                    If swFeat.Name Like "*Punto*" Then
                    Set swRefPt = swFeat.GetSpecificFeature2
                    Set swMathPt = swRefPt.GetRefPoint
                        point_count = UBound(swMathPt)
                                ReDim xValue(point_count)
                                ReDim yValue(point_count)
                                ReDim zValue(point_count)

                        For i = 0 To point_count

                    Set vswRefPt = swMathPt(i)
        
                                xValue(i) = swMathPt.ArrayData(0) * 1000#
                                yValue(i) = swMathPt.ArrayData(1) * 1000#
                                zValue(i) = swMathPt.ArrayData(2) * 1000#
                           
                        Next i

                        '
                        'Creo il file .txt e ci scrivo sopra i valori
    
                        tFilename = swModel.GetPathName
                        sFilename = Left(tFilename, Len(tFilename) - 7)
                        Set fs = CreateObject("Scripting.FileSystemObject")
                        Set f = fs.CreateTextFile(sFilename & ".txt", True)
                         For i = 0 To point_count
                                f.writeline Format(xValue(i)) & " " & _
                                Format(yValue(i)) & " " & _
                                Format(zValue(i))
                        Next i
                    
             End If
             
            End Select
        Set swFeat = swFeat.GetNextFeature
      Loop
   '
   'Cancello i punti
   Call DeletePoints

Ciao
 

jenuary

Utente Standard
Professione: Progettista e Programmatore VB.Net
Software: Solidworks
Regione: Veneto
#53
Mi potresti girare l'intera macro, mi da errore su UBound
Grazie
 

jenuary

Utente Standard
Professione: Progettista e Programmatore VB.Net
Software: Solidworks
Regione: Veneto
#55
Nella fase di scrittura della riga nel file txt, devi aggiungere

For i = 0 To point_count
f.writeline Format(xValue(i)) & " " & _
Format(yValue(i)) & " " & _
Format(zValue(i)) & vbCrLf
Next i

Cosi facendo (vbCrLf) vai a capo
Fammi sapere.
Ciao :redface:
 

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#56
Così facendo è cambiata soltanto la visualizzazione degli zeri dentro al file txt. Adesso ogni riga di zeri è separata da quella seguente da una riga vuota, ma purtroppo gli zeri rimangono.
Sembra in poche parole che riesca a capire di quanti ref point calcolare le coordinate, ma non riesca a trovarli (infatti, ad esempio, se io decido di avere 5 ref point, alla fine nel file txt ho cinque righe, ognuna della quali composta da tre zeri).
 

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#57
Credo di esserci riuscito!!Faceva confusione perchè avevo inserito un ciclo for all'interno di un loop e quindi il compilatore non capiva ciò che chiedevo. Ho modificato il codice in questo modo:


Codice:
Dim swApp                                  As SldWorks.SldWorks
    Dim swModel                                As SldWorks.ModelDoc2
    Dim swFeat                                  As SldWorks.Feature
    Dim swSelMgr                        As SldWorks.SelectionMgr
    Dim swSubFeat                              As SldWorks.Feature
    Dim swSketch                        As SldWorks.Sketch
    Dim swSkPt                      As SketchPoint
    Dim sFeatType                              As String
    Dim swRefPt                                As SldWorks.RefPoint
    Dim swRefPtData                 As SldWorks.RefPointFeatureData
    Dim swRefPointFeatData                      As SldWorks.RefPointFeatureData
    Dim swMathPt                                As SldWorks.MathPoint
    Dim vswRefPt                    As SldWorks.RefPoint
    Dim swMgr                       As SketchManager
    Dim vFeat                       As Variant
    Dim v                                      As Variant
    Dim i                                      As Integer
    Dim j                                      As Long
    Dim sFilename As String
    Dim tFilename As String
    Dim f As Object
    Dim fs As Object
    Dim bRet                                    As Boolean
    Dim boolstatus As Boolean
    Dim longstatus As Long, longwarnings As Long
    Dim nLength                         As Double
    Dim xValue() As Double
    Dim yValue() As Double
    Dim zValue() As Double


...
...
...


'scansione del Feature Manager, se trovo punti di riferimento li scrivo nel file .txt
    Set swFeat = swModel.FirstFeature
    tFilename = swModel.GetPathName
    sFilename = Left(tFilename, Len(tFilename) - 7)
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set f = fs.CreateTextFile(sFilename & ".txt", True)
    
    Do While Not swFeat Is Nothing
        sFeatType = swFeat.GetTypeName
         
            Select Case sFeatType
                Case "RefPoint"
                    If swFeat.Name Like "*Punto*" Then
                    Set swRefPt = swFeat.GetSpecificFeature2
                    Set swMathPt = swRefPt.GetRefPoint
                        
                                ReDim xValue(no_of_items)
                                ReDim yValue(no_of_items)
                                ReDim zValue(no_of_items)

                        

                    Set vswRefPt = swMathPt(i)
        
                                xValue(i) = swMathPt.ArrayData(0) * 1000#
                                yValue(i) = swMathPt.ArrayData(1) * 1000#
                                zValue(i) = swMathPt.ArrayData(2) * 1000#
                           
                    
                                f.writeline Format(xValue(i)) & " " & _
                                Format(yValue(i)) & " " & _
                                Format(zValue(i)) & vbCrLf
                         
                                i = i + 1
      
             End If
                    
            End Select
        Set swFeat = swFeat.GetNextFeature
      Loop
   '
   'Cancello i punti
   Call DeletePoints'scansione del Feature Manager, se trovo punti di riferimento li scrivo nel file .txt
    Set swFeat = swModel.FirstFeature
    tFilename = swModel.GetPathName
    sFilename = Left(tFilename, Len(tFilename) - 7)
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set f = fs.CreateTextFile(sFilename & ".txt", True)
    
    Do While Not swFeat Is Nothing
        sFeatType = swFeat.GetTypeName
         
            Select Case sFeatType
                Case "RefPoint"
                    If swFeat.Name Like "*Punto*" Then
                    Set swRefPt = swFeat.GetSpecificFeature2
                    Set swMathPt = swRefPt.GetRefPoint
                        
                                ReDim xValue(no_of_items)
                                ReDim yValue(no_of_items)
                                ReDim zValue(no_of_items)

                        

                    Set vswRefPt = swMathPt(i)
        
                                xValue(i) = swMathPt.ArrayData(0) * 1000#
                                yValue(i) = swMathPt.ArrayData(1) * 1000#
                                zValue(i) = swMathPt.ArrayData(2) * 1000#
                           
                    
                                f.writeline Format(xValue(i)) & " " & _
                                Format(yValue(i)) & " " & _
                                Format(zValue(i)) & vbCrLf
                         
                                i = i + 1
      
             End If
                    
            End Select
        Set swFeat = swFeat.GetNextFeature
      Loop
   '
   'Cancello i punti
   Call DeletePoints
E' giusto secondo te come impostazione del codice o ci sono errori concettuali?

ciao
 

jenuary

Utente Standard
Professione: Progettista e Programmatore VB.Net
Software: Solidworks
Regione: Veneto
#58
Non l'ho provata perchè nel frattempo stavo creando una mofica parallela alla macro...
Prova questa in allegato, ho inserito un Round nel valore della coordinata, che ti permette di esportare solo 3 cifre decimali (basta cambiarlo per averne 4 o 5 o più).

Ciao
 

Allegati

alxG88

Utente Junior
Professione: Ingegnere Meccanico
Software: SolidWorks, Solid Edge, Inventor, Autocad
Regione: Emilia Romagna
#59
Grazie mille, funziona molto bene anche la tua versione: è sicuramente più accurata della mia, che ho scritto con le mie scarse conoscenze del vba.

A questo punto direi che la macro svolge esattamente ciò che volevo svolgesse: ti rinnovo i miei ringraziamenti per il tuo prezioso aiuto, senza il quale sarebbe stato tutto enormemente più difficile.

Prima di concludere volevo solo capire bene ogni parte del codice, in modo tale da entrare per bene nell'ottica della scrittura di una macro di questo tipo, così magari da essere più preparato in futuro se dovessi scriverne altre o apportare modifiche a questa.
In pratica se ho capito bene la macro agisce in questo modo:

1- Nel main viene indicato alla macro di analizzare, all'interno di uno schizzo, tutte le entità del contorno.

2- Ogni entità del contorno viene scansionata e identificata attraverso le chiamate "ProcessSketchLine, ProcessSketchEllipse, etc...". In pratica la macro identifica ogni entità e capisce se si tratti di una retta, un arco, un'ellisse...

3- Ogni entità del contorno, una volta identificata, viene poi passata ad una function che ne ricava i dati e al termine viene generata una spline in tolleranza +-0.001 mm

4- A questo punto viene chiamato "private sub Punti()", all'interno del quale si stabilisce in quanti punti suddividere la spline, si esegue la suddivisione, si effettua una scansione del feature manager e per ogni ref point trovato si scrivono le relative coordinate su un file txt

5- Infine si chiama in causa "DeletePoints()" che provvede all'eliminazione dei punti di riferimento generati.


Ho capito bene fin qui o ci sono cose che ho capito male?


Ho solo un paio di dubbi:

- Che cos'è "GetSubFeature()", che viene chiamato in causa all'inizio del main?

- Non ho capito bene come agisce la function. Quando di preciso entra in azione e cosa intendi con "ricava i dati di ogni entità del contorno"?


Questi dovrebbero essere gli unici dubbi sul codice (che comunque va benissimo, queste sono solo mie curiosità perchè voglio imparare bene a programmare su SW).


Grazie ancora e ciao
 

jenuary

Utente Standard
Professione: Progettista e Programmatore VB.Net
Software: Solidworks
Regione: Veneto
#60
Hai capito bene tutti i passaggi dall'1 al 5

Per quanto riguarda "GetSubFeature()" mi serve a inizio macro a memorizzare l'ultima fature dell'albero, infatti eseguo la scansione partendo dal fondo del feature manager, e salvo l'ultima feature in una variabile.
Quando passiamo alla "DeletePoints()", comincio a cancellarli dal fondo e interrogando il nome della feature, mi fermo ed esco quando trovo la feature memorizzata all'inizio.
Questo è un sistema che utilizzo per rendere la macro veloce, infatti prova a pensare di avere una parte con 200 feature o piu, partendo a scansionare dall'alto, mi devo passare quasi tutte le feature per cancellare alla fine quelle in piu, mentre cosi parto dal fondo e mi fermo dove mi serve.
E' una sorta di Undo.

Per quanto riguarda le function, se attivi da VBA dentro il menu a tendina Visualizza-> Finestra Immediata, ad ogni Debug.Print, leggi il risultato in questa finestra (coordinate, tipo entità ecc.), che si apre sotto l'intefaccia.

Prova e fammi sapere
Ciao