Hi everyone
I want to make plugin for AutoCAD but i have some problems.
I want to make plugin that connect to server, send there current image and then server do something with it and send back results.
So I am actualy making 2 plugins. One on server side, other on client side.
Server side code:
Imports System.Net.Sockets Imports System.Text Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports System.Net Imports System.Threading Imports Autodesk.AutoCAD.EditorInput Namespace serverACDrendering Public Class Commands Dim close As Boolean = False Dim MAX_CLIENTS As Integer = 5 Dim queue(MAX_CLIENTS) As ClientWrapper Dim currentClient As Integer = 0 <CommandMethod("StartServer")> Public Sub StartServer() For i As Integer = 0 To MAX_CLIENTS queue(i) = Nothing Next Dim receiverThread As Thread = New Thread(AddressOf receiver) Dim transmitterThread As Thread = New Thread(AddressOf transmitter) receiverThread.Start() Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor ed.WriteMessage("\nreceiver thread started\n}") transmitterThread.Start() ed.WriteMessage("\ntransmitter thread Started\n") While (Not close) ed.WriteMessage("\nCreated both threads... Time to rock ...\n") End While End Sub
<CommandMethod("StopServer")> Public Sub StopServer() close = False End Sub End Class
So i have two more threads receiver thread and transmitter thread. First is getting clients and get file from them, second send results back to them.
The problem
While (Not close) ed.WriteMessage("\nCreated both threads... Time to rock ...\n") End While
In this while loop i shold take one client and do something with it.
When this loop starts i cant stop it from autocad with StopServer command (I think because autocad is busy).
I can't do this in seperate thread because autoCAD don't do multithreading.
What can i do to put this work in background ?
Regards Domen
According to AutoCAD Help, CVPORT is the identification number of the current viewport. It's 1 for all paper spaces, 2 for model space (first main viewport), 3 and so on for next viewports if you split the screen (see the below screenshot).
Kean Walmsley has some useful links about rendering in AutoCAD, start from here: http://through-the-interface.typepad.com/through_the_interface/2007/04/taking_a_snapsh.html
Based on his links, I added some comments for you to easily understand:
Using doc ' Get AutoCAD working database, it's not the current MDI document database Dim workDb As Database = HostApplicationServices.WorkingDatabase ' Set the open drawing as a working database HostApplicationServices.WorkingDatabase = doc.Database filePath = ServerFolder + imageFileName ' Get the identification number of the current viewport ' 1 for all paper spaces ' 2 for 1st viewport in model space ' 3 for 2nd viewport in model space ' n for (n-1)th viewport in model space Dim viewportNumber As Integer = System.Convert.ToInt32(Application.GetSystemVariable("CVPORT")) ' Get AutoCAD's GS view for this viewport Dim gsv As GraphicsSystem.View = doc.GraphicsManager.GetGsView(viewportNumber, True) ' Clone this view for the actual snapshot Using view As GraphicsSystem.View = gsv.Clone(True, True) ' Specify the viewport number held in CVPORT doc.GraphicsManager.SetViewFromViewport(view, viewportNumber) Using dev As Device = doc.GraphicsManager.CreateAutoCADOffScreenDevice() ' Set the render type dev.DeviceRenderType = RendererType.FullRender ' Add the view to the device dev.Add(view) ' Render the view to an image Dim bitmap As Bitmap = view.RenderToImage() Using bitmap bitmap.Save(filePath) fileStream = File.OpenRead(filePath) _client.Result = fileStream End Using End Using End Using ' Restore the previous working database back HostApplicationServices.WorkingDatabase = workDb End Using
The server now renders the view on the top position, regardless of the 3D view sending from the client. I will have it fixed.
-Khoa
Thanks for reply
I was trying to repair code because after this code runs once the AutoCAD crash.
Is it posible that we are doing domething wrong after opening file and it crash and render as resoult of that bug?
i was running code without part bellow and on server side it opened dwg file as it should. (if i use whole function it opens two windows one with dwg file, second with my dwg file in top position-probably one that is later rendered)
Using doc ' Get AutoCAD working database, it's not the current MDI document database Dim workDb As Database = HostApplicationServices.WorkingDatabase ' Set the open drawing as a working database HostApplicationServices.WorkingDatabase = doc.Database filePath = ServerFolder + imageFileName End Using ' Restore the previous working database back HostApplicationServices.WorkingDatabase = workDb End Using
I also put line for getting CVPORT and it is ok it returns 2, but when i put line where we make gsv view i crash.
I hope it will help you
I could not fix the problem of rendering at the top position regardless of current 3D view. So I put my question to the code author Kean Walmsley at his blog link. He will help us out.
The problem is the code GraphicsSystem.View gsv = doc.GraphicsManager.GetGsView(viewportNumber, true) does not get the current 3D view, the method RenderToImage() does render on the top view.
If I test to add the code gsv.Orbit(1, 1) to change the orbit view, the rendering image will be in 3D view. So we still are missing code to set 3D view before RenderToImage method. I hope someone or Kean will come for help.
-Khoa
Hi Khoa
ths weekend i was searching for some other method to do this rendering. Maybe i was to much complicating things.
what if i just open file, then i send to autocad command RENDER and i take picture rendered and send it back.
I will try to put idea to code today and then posted here
Private Sub Render(dwgFileName As String, imageFileName As String) Try Dim filePath As String = ServerFolder + dwgFileName Dim responseStream As MemoryStream = _client.File If Not Directory.Exists(ServerFolder) Then Directory.CreateDirectory(ServerFolder) End If If File.Exists(filePath) Then File.Delete(filePath) End If If File.Exists(ServerFolder + imageFileName) Then File.Delete(ServerFolder + imageFileName) End If Dim fileStream As FileStream = File.OpenWrite(filePath) responseStream.WriteTo(fileStream) fileStream.Close() ' Open the new saved drawing in AutoCAD 2013 Dim docCol As DocumentCollection = Application.DocumentManager Dim doc As Document = DocumentCollectionExtension.Open(docCol, filePath) 'PROBLEM '' need to set render to file on and path to c:\ServerFolder\Picture.png doc.SendStringToExecute("RENDER ", True, False, True) Catch ex As System.Exception _editor.WriteMessage(ex.Message + vbLf + ex.StackTrace) End Try End Sub
here is some code. The only problem is how to set right path for saving rendered pictures.
if somehow I can say on server side save output to C:\ServerFolder\Picture.pngi am saved.
if it is possible i could do this also like rendernig with command but so far i dodn't find solution how to set in command propt.
Hi dj-nemo,
I replied to your other post. Pasting the same here for completeness.
Have you tried using the command line version of the Render command. This will provide you the option to specify the path for the render image.
Try "-Render" inside AutoCAD. You can then pass the same parameters using code.
Hope this helps.