Italian (IT)

Tratto da programmazione.it scritto da Dario Guadagno

In questo articolo, vedremo come esportare il lavoro fatto con Java3D in formati standard e quindi particolarmente portabili, come VRML e la sua evoluzione X3D. Il package CyberX3D è un sottoinsieme della libreria CyberGarage, realizzata dal programmatore giapponese Satoshi Konno, contenente un insieme di classi e metodi orientati alla realtà virtuale ed alla programmazione in grafica 3D.

Satoshi Konno, nato nel 1972 a Tokyo, lavora da anni nell’ambito della programmazione di sistemi in realtà virtuale, e dal 1996 ha iniziato a lavorare al CyberGarage, un insieme di prodotti ideati per semplificare o ottimizzare la programmazione di ambienti tridimensionali. La libreria CyberGarage, oltre a CyberX3D (scritto sia per programmatori Java che C++), contiene anche altri package interessanti, alcuni dei quali persino premiati da diversi riconoscimenti attestanti l’eccellente qualità.

Rilasciato nel 2003, CyberX3D è un package per programmatori Java che intendono interoperare con file e ambienti VRML o X3D. Utilizzando CyberX3D è possibile creare o utilizzare, in maniera piuttosto semplificata, classi e metodi per leggere/scrivere file VRML o X3D, reperire o modificare informazioni relative allo scene graph di un ambiente 3D, disegnare scene tridimensionali da esportare in uno dei suddetti formati.

L’utilizzo del package è subordinato alla presenza nel proprio sistema della piattaforma Java 2 Standard Edition e delle API Java3D. L’installazione di CyberX3D avviene, facilmente, copiando il package nella directory del Run Time Environment della JVM.

Tratto da programmazione.it, scritto da Dario Guadagno

In quest'ultima parte, tratteremo alcuni problemi che si potrebbero verificare durante la scrittura di programmi in grafica 3D in ambiente Java, e saranno spiegati alcuni dettagli relativi al motore 3D.

Come accennato nella prima parte dell'articolo, Java3D si appoggia su librerie native, per cui è da esse che deriva le proprie feature principali, mentre non è in grado di fornire supporto per alcune funzionalità, come la gestione delle ombre o delle texture animate, superfici trasparenti o specchi). Tuttavia, queste non sono limitazioni di Java3D, ma delle librerie native. Le operazioni citate sono infatti molto dispendiose in termini di risorse e non vengono utilizzate in grafica 3D in tempo reale. È lecito aspettarsi che quando l’evoluzione tecnologica porterà gli standard 3D a supportare questo tipo di caratteristiche, anche Java3D ne fornirà il supporto.

Java3D non è però solo un semplice wrapper su API esistenti: il suo motore si occupa anche di ottimizzazioni e operazioni aggiuntive che non sono previste nelle API native. Il runtime engine sceglie l’ordine di attraversamento dell’albero e non è limitato ad una direzione di tipo sinistra-destra o sopra-sotto, quindi può utilizzare strategie per l'ottimizzazione della visualizzazione. La rappresentazione di un'immagine tridimensionale avviene seguendo il seguente schema:

  • definizione del view volume, ovvero della porzione di spazio visibile all’utente;
  • rendering: conversione del view volume in un’immagine 2D;
  • rasterization: l’immagine viene convertita in una griglia di pixel;
  • shading: viene impostato il colore dei pixel.

Tutte le suddette operazioni sono eseguite direttamente, e in maniera trasparente a programmatore ed utente, dalla Java Virtual Machine, che immediatamente dopo, mostra l’effettiva scena attiva, pronta all’eventuale interazione. Ulteriori problematiche potrebbero essere connesse ad altre due segnalazioni: le classi di Java 3D non sono serializzabili e, come noto, richiedono un notevole impiego di risorse. Quest'ultimo punto, in particolare, merita una cura in più: se da un lato, chiaramente, esso determina un rallentamento nelle prestazioni, peraltro piuttosto lieve e sicuramente accettabile, dall'altro, in caso di scene particolarmente complesse e cariche di oggetti, può addirittura causare il crash dell'applicazione per problemi di insufficienza di memoria (Out of Memory Error).

Il problema si presenta perché, di default, la JVM ricorre ad un heap di dimensioni contenute, ideale per la maggior parte delle applicazioni eseguite, ma non sufficiente nel caso di sistemi più complessi. È possibile aggirare tale rischio ampliando l’heap a disposizione della JVM, specificando dei parametri aggiuntivi all’atto di mandare in esecuzione l'applicazione. Il progetto, in generale, presenta una certa semplicità d’uso anche se dà l’idea di essere stato sviluppato un po’ in disparte rispetto alle altre tecnologie Java. L’incompatibilità con Swing ne è un esempio (come la classe Locale che trova un duplicato in java.util) che potrebbe frenare progetti ambiziosi su Java3D.

Nonostante alcune limitazioni e complessità aggiuntive, comunque, è indubbio che Java3D sia un potentissimo strumento a disposizione dei programmatori Java. Le Api completano l’offerta della piattaforma, introducendo un elemento chiave quale la grafica 3D e fornendo un'ulteriore preziosa funzionalità all'intera tecnologia Java.

Tratto da programmazione.it, scritto da Dario Guadagno

Una soluzione alternativa per gestire gli eventi può essere ottenuta sfruttando il fatto che la Canvas3D, in quanto Component, è una possibile sorgente di eventi. Da ciò, catturando gli eventi generati dalla Canvas3D, e quindi le interazioni dell'utente con la scena, e sfruttando i metodi offerti dalla classe PickCanvas, che restituisce un riferimento all'oggetto (il nodo dell'albero) su cui l'utente ha cliccato, è possibile simulare una gestione di eventi basata sulle interazioni con gli oggetti 3D della scena.

Per lavorare in tal senso, d'altra parte, è bene ricordare che gli oggetti "interattivi" devono essere pick-reportable, cioè devono poter essere letti dal PickCanvas:

nodo3d.setCapability(TransformGroup.ENABLE_PICK_REPORTING);

Qualora si voglia gestire la possibilità di spostare/rimuovere oggetti dall'albero della scena in seguito a qualche interazione, essi devono anche essere detachable, cioè rimuovibili dallo Scene Graph, oppure devono consentire la lettura e scrittura delle loro proprietà all'interno dell'albero:

nodo3d.setCapability(BranchGroup.ALLOW_DETACH); //rende l'oggetto detachable

/* Lettura e modifica delle trasformazioni */
nodo3d.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
nodo3d.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

/* Lettura e modifica dei figli nel sottoalbero radicato nel nodo oggetto3d */
nodo3d.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
nodo3d.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
nodo3d.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);

Una volta definita la scena e le eventuali interazioni, basterà rendere visibile il frame che contiene la Canvas3D per visualizzare la nostra prima scena tridimensionale. Con le prime tre parti di questo articolo sono stati mostrati gli aspetti fondamentali della programmazione in Java 3D.

Tratto da programmazione.it, scritto da Dario Guadagno

La scena, di default, indipendentemente dalle dimensioni del frame che la contiene, ha larghezza 2, il punto più a sinistra è posto alla coordinata -1 e l’estremo a destra è alla coordinata +1; al centro del frame è posta l’origine e l’asse della profondità è orientato secondo il verso “uscente” dallo schermo. L'asse dell'altezza ha dimensione calcolata in rapporto alla larghezza: ad esempio, se un frame ha altezza doppia rispetto alla larghezza, il punto più alto del frame avrà coordinata 2, e il più basso -2.

È possibile definire delle reazioni ai movimenti del mouse nella scena (specializzazioni della classe MouseBehavior), o alle specifiche interazioni su un oggetto 3D (specializzazioni della classe PickMouseBehavior), ma il meccanismo non è semplicissimo ed è certamente più macchinoso di quanto non accada con la normale gestione ad eventi. D'altra parte, alcune convenzioni adottate da Java 3D sono facilmente utilizzabili e permettono di gestire i movimenti "continui" degli oggetti tridimensionali, come la traslazione o la rotazione:

  • pressione del pulsante sinistro del mouse e trascinamento, per la rotazione di un oggetto, gestita dalla classe PickRotateBehavior.
  • Pressione del pulsante destro del mouse e trascinamento, per lo spostamento di un oggetto lungo l’asse orizzontale o verticale, gestita dalla classe PickTranslateBehavior.
  • Pressione del pulsante sinistro del mouse e, contemporaneamente, del tasto ALT della tastiera (tale combinazione equivale alla pressione del pulsante centrale nei mouse three button) e trascinamento, per avvicinare o allontanare un oggetto (spostamento lungo l’asse della profondità), gestita dalla classe PickZoomBehavior).

Le scelte relative ai componenti tridimensionali di una scena sono dovute anche al fatto che, chiaramente, i cambiamenti a runtime di un ambiente tridimensionali sono ben più “pesanti” di quelli all’interno di applicazioni 2D. Limitare e standardizzare i movimenti e rendere più "statici" gli oggetti alleggerisce il lavoro a runtime del motore 3D.

Tratto da programmazione.it, scritto da Dario Guadagno

Le API Java 3D sono una libreria di classi e metodi specifiche per la realizzazione di applicazioni dotate di interfaccia grafica tridimensionale. Java 3D consente la produzione in tempo reale di grafica 3D tramite un insieme di API omogenee e multipiattaforma. Queste non si occupano del rendering a basso livello delle immagini: questa operazione è delegata dal motore di rendering di Java 3D alle librerie native della piattaforma sottostante, come OpenGL e Direct3D.

L'installazione delle API può avvenire semplicemente eseguendo il comodo tool autoinstallante scaricabile dal sito di Sun Microsystems. In Java 3D, il concetto fondamentale è quello dello scene graph: un albero a cui si appendono tutti gli oggetti della scena 3D, intendendo con tale termine non solo gli elementi da visualizzare, ma anche le istruzioni per rappresentarli.

L’albero è radicato nell’Universo Virtuale (Virtual Universe) che, a sua volta, ha uno o più figli Locale (letteralmente, dei luoghi all’interno dell’universo), che rappresentano le scene tridimensionali. Lo scene graph viene percorso dal motore di Java 3D per trovare i dati per creare l'immagine, perciò qualsiasi cosa si desideri abbia un'influenza sulla scena va messa nello scene graph.

Da ogni nodo Locale partono due rami (branches) principali: il content branch e il view branch: il primo contiene gli oggetti da visualizzare, il loro colore, dove sono messi nello spazio e tutte le altre informazioni rilevanti; il secondo contiene tutto quello che riguarda “il vedere” la scena, ad esempio i dispositivi di input/output, punto di vista ecc.

La creazione dell’Universo Virtuale, del contesto locale e di tutti gli aspetti relativi al view branch può essere effettuata automaticamente utilizzando la classe SimpleUniverse fornita di default dal package, in com.sun.j3d.utils.universe.*

Il disegno tridimensionale viene creato all'interno di un oggetto Canvas3D, che è un'estensione della classe Component, per cui può semplicemente essere aggiunto ad un frame; tuttavia, non è un container, quindi non può contenere altri componenti. La Canvas3D viene creata a partire dal view branch, e riempita, quindi, con gli elementi del content branch. Gli oggetti tridimensionali immessi nella scena, in effetti, non sono altro che dei rendering delle immagini descritte dai nodi, per cui, non è possibile associare degli eventi da catturare e gestire, secondo la normale programmazione a eventi di Java, ma è possibile definire dei behavior, cioè delle reazioni degli oggetti tridimensionali all'interazione dell'utente con la scena.

Come detto, quindi, ogni elemento della scena, sia esso un oggetto 3D, una luce o una qualsiasi entità che definisca le modalità di visualizzazione dell'ambiente, non è altro che un nodo del grafo della scena. Due nodi, tuttavia, hanno una funzione particolare: i BranchGroup, radici di sottoalberi di oggetti con proprietà comuni, e i TransformGroup, che definiscono delle trasformazioni (rotazioni, spostamenti lungo uno degli assi ecc.) associate a tutti gli elementi del loro sottoalbero.

Le foglie dello Scene Graph sono, tipicamente, gli oggetti fisici che popolano la scena.

Continua la serie sulle possibilità offerte dagli ambienti di sviluppo per estendere le proprie funzionalità, con una piccola parentesi non totalmente in tema, ma decisamente interessante per completare quanto detto nel precedente articolo riguardo la stesura di moduli per NetBeans grazie alle sue feature.

Chi di voi non ha pasticciato almeno una volta con le macro di Microsoft Office alzi la mano e faccia un esame di coscienza; tutti gli altri ricorderanno benissimo come da molti anni, grazie alle API della suddetta suite, sia possibile con poche righe di Visual Basic scrivere delle utilissime funzioni per i vari programmi di Office con tanto di editor di GUI e di sorgente — come in una versione Express del Visual Studio — nell'amabile logica di programmazione orientata agli eventi.

Finalmente anche OpenOffice.org dalla versione 2.0.4 e StarOffice — versione estesa e commerciale di OpenOffice.org — come avviene per le varie distribuzioni di editor basate su Eclipse, dalla 8 update 4, ha deciso di offrire le stesse possibilità; chiaramente con il linguaggio di programmazione Java, alla base di OpenOffice.org, ed un interessante modulo per NetBeans: OpenOffice.org API plugin. Pare infatti che questo plug-in permetta, grazie al riconoscimento e all'utilizzo delle API di OpenOffice.org, di ottimizzare la produttività per lo sviluppo delle nuove estensioni (file .oxt) per la suite di office automation.

Sul blog ufficiale di Sun Microsystems troviamo infatti l'interessante tutorial “Developing OpenOffice extensions using Java and NetBeans”, che illustra le operazioni fondamentali per giungere al nostro scopo utilizzando NetBeans 6, il JDK 6, OpenOffice.org 2.0.4 e l'OpenOffice.org SDK. Il tutorial si conclude con un paio di brevi video dimostrativi.

Come segnalato anche nel citato documento, è possibile vedere la presentazione della nuova infrastruttura ad estensioni di OpenOffice.org presentata all'OpenOffice.org Conference o, meglio ancora, leggere sul wiki di OpenOffice.org come sia possibile integrare l'IDE e la suite di office automation prodotti da Sun. Dopo questa parentesi, nel prossimo articolo concluderemo la serie in corso, osservando come sia possibile estendere le funzionalità di un ulteriore ambiente di sviluppo Java-based.

Tratto da programmare.it di Pierpaolo Cira

Come pilotare Rhinoceros dal plug-in
Presento qui i listati dei file .NET del plug-in di base con alcuni comandi funzionanti, presi direttamente dal sito della Mc Neel, in modo da avere qualche esempio su come strutturare l'interfaccia con Rhinoceros.
 
RhinoPlugInBasePlugIn.vb
Public Class RhinoPlugInBasePlugIn Inherits RMA.Rhino.MRhinoUtilityPlugIn
 Public Overrides Function PlugInID() As System.Guid
  Return New System.Guid("{722abf0d-d9d2-4cd7-8637-d9b11148b7ed}")
 End Function

 Public Overrides Function PlugInName() As String
  Return "RhinoPlugInBase"
 End Function

 Public Overrides Function PlugInVersion() As String
  Return "1.0.0.0"
 End Function

 Public Overrides Function OnLoadPlugIn() As Integer
  '''<returns>        
  '''  1 = initialization succeeded, let the plug-in load   
  '''  0 = unable to initialize, don't load plug-in and display an error dialog  
  ''' -1 = unable to initialize, don't load plug-in and do not display an error  
  '''      dialog. Note: OnUnloadPlugIn will not be called       
  '''</returns>    
  Return 1
 End Function

 Public Overrides Sub OnUnloadPlugIn()
 End Sub
End Class
RhinoPlugInBasePlugInAttributes.vb 
Public Class MyPlugIn1Attributes Inherits RMA.Rhino.MRhinoPlugInAttributes
 Public Overrides Function Address() As String
  Return "undefined"
 End Function

 Public Overrides Function Country() As String
  Return "Italy"
 End Function

 Public Overrides Function Email() As String
  Return "This email address is being protected from spambots. You need JavaScript enabled to view it."
 End Function

 Public Overrides Function Fax() As String
  Return "undefined"
 End Function

 Public Overrides Function Organization() As String
  Return "Tessaro Bruno"
 End Function

 Public Overrides Function Phone() As String
  Return "undefined"
 End Function

 Public Overrides Function UpdateURL() As String
  Return "undefined"
 End Function

 Public Overrides Function Website() As String
  Return "undefined"
 End Function
End Class
AddLayerCommand.vb 
Imports RMA.Rhino Imports RMA.OpenNURBS Imports RMA.Rhino.RhUtil

Public Class AddLayerCommand Inherits RMA.Rhino.MRhinoCommand
 Public Overrides Function CommandUUID() As System.Guid
  Return New Guid("{fe405805-c87d-4445-a48c-6a15a6c70817}")
 End Function

 Public Overrides Function EnglishCommandName() As String
  Return "AddLayerCommand"
 End Function

 Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result
  Dim layer_table As MRhinoLayerTable = context.m_doc.m_layer_table
  Dim unused_name As String = ""
  layer_table.GetUnusedLayerName(unused_name)

  Dim gs As New MRhinoGetString()
  gs.SetCommandPrompt("Name of layer to add")
  gs.SetDefaultString(unused_name)
  gs.AcceptNothing(True)
  gs.GetString()
  If (gs.CommandResult() <> IRhinoCommand.result.success) Then
   Return gs.CommandResult()
  End If

  Dim layer_name As String = gs.String()
  layer_name = layer_name.Trim()
  If (String.IsNullOrEmpty(layer_name)) Then
   RhUtil.RhinoApp().Print("Layer name cannot be blank." + vbCrLf)
   Return IRhinoCommand.result.cancel
  End If

  If (RhUtil.RhinoIsValidName(layer_name) = 0) Then
   RhUtil.RhinoApp().Print(layer_name + " is not a valid layer name." + vbCrLf)
   Return IRhinoCommand.result.cancel
  End If

  Dim layer_index As Integer = layer_table.FindLayer(layer_name)
  If (layer_index >= 0) Then
   Dim msg As String = "A layer with the name " + layer_name + " already exists." + vbCrLf
   RhUtil.RhinoApp().Print(msg)
   Return IRhinoCommand.result.cancel
  End If

  Dim layer As New OnLayer()
  layer.SetLayerName(layer_name)
  layer_index = layer_table.AddLayer(layer)
  If (layer_index < 0) Then
   RhUtil.RhinoApp().Print(String.Format("Unable to add {0} layer." + vbCrLf, layer_name))
   Return IRhinoCommand.result.failure
  End If
  Return IRhinoCommand.result.success
 End Function
End Class 
ExtendSurfaceCommand.vb 
Imports RMA.Rhino Imports RMA.OpenNURBS Imports RMA.Rhino.RhUtil

Public Class ExtendSurfaceCommand Inherits RMA.Rhino.MRhinoCommand
 Public Overrides Function CommandUUID() As System.Guid
  Return New Guid("{1120623a-268f-4986-a9e5-dd287763159c}")
 End Function

 Public Overrides Function EnglishCommandName() As String
  Return "ExtendSurfaceCommand"
 End Function

 Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result
  Dim go As New MRhinoGetObject
  go.SetCommandPrompt("Select edge of surface to extend")
  go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.edge_object)
  go.SetGeometryAttributeFilter(IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.edge_curve)
  go.GetObjects(1, 1)
  If (go.CommandResult() <> IRhinoCommand.result.success) Then
   Return go.CommandResult()
  End If

  Dim objref As IRhinoObjRef = go.Object(0)
  Dim srf As IOnSurface = objref.Surface()
  If (srf Is Nothing) Then

   RhUtil.RhinoApp().Print("Unable to extend polysurfaces." + vbCrLf)
   Return IRhinoCommand.result.nothing
  End If

  Dim brep As IOnBrep = objref.Brep()
  Dim face As IOnBrepFace = objref.Face()
  If (brep Is Nothing Or face Is Nothing) Then Return IRhinoCommand.result.failure
  If (face.m_face_index < 0) Then Return IRhinoCommand.result.failure

  If (Not brep.IsSurface()) Then
   RhUtil.RhinoApp().Print("Unable to extend trimmed surfaces." + vbCrLf)
   Return IRhinoCommand.result.nothing
  End If

  Dim trim As IOnBrepTrim = objref.Trim()
  If (trim Is Nothing) Then Return IRhinoCommand.result.failure

  Dim edge_index As IOnSurface.ISO = trim.m_iso
  Dim dir As Integer = edge_index Mod 2
  If (srf.IsClosed(1 - dir)) Then
   RhUtil.RhinoApp().Print("Unable to extend surface at seam." + vbCrLf)
   Return IRhinoCommand.result.nothing
  End If

  If (edge_index < IOnSurface.ISO.W_iso Or edge_index > IOnSurface.ISO.N_iso) Then
   RhUtil.RhinoApp().Print("Selected edge must be an underlying surface edge." + vbCrLf)
   Return IRhinoCommand.result.nothing
  End If

  Dim myface As OnSurface = srf.DuplicateSurface()
  If (myface Is Nothing) Then
   Return IRhinoCommand.result.failure
  End If

  Dim rc As Boolean = RhUtil.RhinoExtendSurface(myface, edge_index, 5.0, True)
  If (rc) Then
   Dim mybrep As New OnBrep()
   mybrep.Create(myface)
   Dim obj As New MRhinoBrepObject()
   obj.SetBrep(mybrep)
   context.m_doc.ReplaceObject(New MRhinoObjRef(objref.Object()), obj)
   context.m_doc.Redraw()
  End If
  Return IRhinoCommand.result.success
 End Function
End Class 
LanguageCommand.vb 
Imports RMA.Rhino Imports RMA.OpenNURBS Imports RMA.Rhino.RhUtil

Public Class LanguageCommand Inherits RMA.Rhino.MRhinoCommand
 Public Overrides Function CommandUUID() As System.Guid
  Return New Guid("{d8dda157-454c-4e9b-a740-7df8815fe100}")
 End Function

 Public Overrides Function EnglishCommandName() As String
  Return "LanguageCommand"
 End Function

 Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result         Dim settings As MRhinoAppSettings = RhUtil.RhinoApp.AppSettings      
  Dim appearance As IRhinoAppAppearanceSettings = settings.AppearanceSettings()
  Dim id As Integer = CType(appearance.m_language_identifier, Integer)
  Dim culture As New System.Globalization.CultureInfo(id)
  RhUtil.RhinoApp.Print("The current language is " + culture.EnglishName + vbCrLf)
  Return IRhinoCommand.result.success
 End Function
End Class 
Si possono cercare nella guida di riferimento gli altri comandi impiegabili nei plug-in. Il resto è la classica programmazione in Visual Basic .NET. Non sto qui a pubblicare una guida a tale linguaggio, in rete ne esistono già di ottime.

Analizziamo il plug in di base generato dal wizard per studiare la struttura di base di un plug-in per Rhino.

File: nomepluginAttributes.vb Qui sono salvate le stringhe con i dati dello sviluppatore del plug-in e del plug-in stesso

File: nomepluginPlugIn.vb Class PlugInID (identificatore unico del plug-in) Function PlugInName (nome) Function PlugInVersion (versione) Function OnLoadPlugIn (codice da eseguire all'avvio del plug-in) Function OnUnloadPlugIn (codice da eseguire alla chiusura del plug-in) Function OnDisplayPlugInHelp (aiuto plug-in)

File: nomepluginCommand.vb Function CommandUUID (identificatore unico del comando) Function EnglishCommandName (nome comando da digitare sulla command bar e uguale a nome file vb) Function RunCommand (codice del comando da eseguire)

Per aggiungere altri comandi con il corretto UUID usare il menu: Progetto -> Aggiungi nuovo elemento -> Rhino command

Per un'eventuale integrazione e uso di database SQL su file Access .mdb Per poter disporre di un database SQL nell'applicazione si può usare il seguente driver di .NET Framework: Microsoft Jet OLEDB 4.0 E' integrato in .NET Framework e lavora su file MDB: Dati -> Aggiungi nuova origine dati Nuova connessione Origine dati: File di database Microsoft Access (OLE DB) Nome di file di database: ...file.mdb

Vediamo com'è strutturato un plug-in e come muovere i primi passi. Aprire Visual Basic 2005 Express. Scegliamo la voce Crea progetto e quindi il template Rhino Plug-in. Attendere il caricamento del wizard.

Scegliere il nome del progetto. Plug-in type: General Utility Plug-in. Scegliere: Add this plug-in to the help menu. Premere sul bottone Next. Inserire le info dello sviluppatore. Premere sul bottone Finish.

Si ottiene un progetto plug-in di base pronto.

Ora possiamo scrivere tutto il codice sorgente necessario alla nostra extension. Per ora non scriviamo nulla, vediamo direttamente cosa fare al termine del lavoro.

Scegliere il menu Genera e generare il progetto. Avviare Rhinoceros 4.0 selezionare il menù: Strumenti -> Opzioni (ovvero Tools -> Options). Aprire la sezione Plug-ins. Premere il pulsante Install. Scegliere la dll creata da VBasic che si trova nella cartella:  Documenti\Visual Studio 2005\Projects\ProjectName\bin\Release La plug-in è ora correttamente installata su Rhinoceros 4.0 ed è utilizzabile richiamando i comandi.

Page 6 of 8


© 2017 Bruno Tessaro. My life in the web. All right reserved.

This website uses cookies to ensure you get the best experience on our website.