Lab 8 – User Interface (Non CUI API)

 

In this lab, there will be three sections that will show how to use the .NET API to do the following:

 

  • Define a custom context menu.
  • Add a tab to the AutoCAD’s Options dialog.
  • Add a label to the user control that will run a command using Drag and Drop.

 

Custom Context Menu

 

To add a context menu without running a command we need to have our code run when our dll is loaded. To perform the load-time initialization, an AutoCAD .NET application can implement the IExtensionApplication .NET interface, and expose an assembly-level attribute which specifies this class as the ExtensionApplication.  The class can then respond to one-time load and unload events.  Paste these steps into the Class you have been using for the previous labs. Or open the Lab8 project that already has these steps.

 

' 1. Modify the asdkClass1 class to implement the IExtensionApplication interface.

' Note: Visual Studio Automatically adds a couple of required methods

' Initialize() and Terminate. Look for these methods below the other existing methods.

' Copy and paste so steps 23 and 37 are inside the Initialize procedure and step 24

' is inside the Terminate procedure

' Also add this attribute by uncommented the next line of code. (needs to be oustide of the class)

'' This line is not mandatory, but improves loading performances

' <Assembly: ExtensionApplication(GetType(adskClass))>

 

' 2. Declare a member variable as ContextMenuExtension. It will be instantiated

' in step 6

' (This class is a member of the Autodesk.AutoCAD.Windows namespace).

 

 

' 3. Create a private procedure named AddContextMenu.

' Note: Put the End Sub after step 12.

 

 

' 4. Declare an editor variable. Instantiate it by making it equal to the

' Editor property of the Application.DocumentManager.MdiActiveDocument.Editor

 

 

' 5. Add a Try Catch block.

' Note: put the Catch below step 11. Have the catch use an

' Application.Exception name it "ex"

' Put the End Try below step 12.

 

' 6. Make the ContextMenuExtension declared in step 2 equal

' to a New ContextMenuExtension

 

 

' 7. Make the Title property of the ContextMenuExtension

' instantiated in step 7 equal to "Circle Jig". (it is going

' to run the command completed in Lab2.

 

 

' 8. Declare a MenuItem variable named mi. Instantiate by

' making it eaual to a New MenuItem. For the string parameter

' use a string like "Run Circle Jig".

 

 

' 9. The way the Context menu works is that for each menu entry, we specify a

' specific member function to be called handling the menu-clicked event.

' Use the VB keyword AddHandler and AddressOf to specify that we want

' the event handled by one of our functions. For the object paramater

' use the Click event of the MenuItem created in step 8. For the delegate

' parameter use a function we will create in step 20 named CallbackOnClick.

 

 

' 10. Use the Add method of the MenuItems collection of the

' ContextMenuExtension instantiated in step 6. Pass in the

' MenuItem created in step 8.

 

 

' 11. Use the AddDefaultContextMenuExtension of the Application.

' Pass in the ContextMenuExtension

 

 

' 12. Use the editor variable created in step 4 and write a message.

' to the command line Something like"

' "Error Adding Context Menu: " + ex.Message

 

 

' 13. Create a procedure named RemoveContextMenu.

' Note: Put the End Sub after step 19.

 

 

'14. Declare an document variable. Instantiate it by making it

'    equal the MdiActiveDocument

 

' 15. Add a Try Catch block.

' Note: put the Catch below step 18. Have the catch use an

' Application.Exception name it "ex"

' Put the End Try below step 19.

 

' 16. Use an "If Then" statement and test if the ContextMenuExtension

' declared in step 2 is nothing (Not Is  Nothing).

' Note: put the "End If" below step 18

 

 

' 17. In the if statement, use RemoveDefaultContextMenuExtension

' of the Application. Pass in the ContextMenuExtension declared

' in step 2

 

' 18. Make the ContextMenuExtension declared in step 2 equal to nothing

 

' 19. Use the editor and write a message. Something like

' "Error Removing Context Menu: " + ex.Message

' Use an "If Then" statement and test if the activeDoc

' declared in step 14 is nothing (Not Is  Nothing).

' In AutoCAD 2013, If AutoCAD is being closed, we may not have access to the ' active document here.

 

 

' 20. Create a procedure named CallbackOnClick. This is the method that

' will be called when the Menu Item is clicked. Set in step 9.

' Note: Put the End Sub after step 22.

 

 

' 21. Use the using statement and create a variable as a DcoumentLock.

' Instantiate it by making it equal to the .MdiActiveDocument.LockDocument

' method. (Because this event is running outside of the Document context we

' need to lock the document). By design, AutoCAD’s data is stored in documents,

' where commands that access entities within them have rights to make

' modifications.  When we run our code in response to a context-menu click,

' we are accessing the document from outside the command structure.

' In order to unlock the document we simply dispose DocumentLock object

' returned on the original lock request.

' Note: put the End Using statement after step 22.

 

 

' 22. Call the CircleJig() function.

 

 

' 23. Inside the Initialize procedure. (created by Visual Studio in step 1) add

' a call to AddContextMenu(). This will add the Context menu when this .NET dll

' is loaded.

' Note: Proceed to step 24 below

 

 

' 37. Inside the Initialize procedure. Uncomment this line after doing

' steps through 24 - 27

' This will run this function when the dll is loaded in AutoCAD

' AddTabDialog()

 

 

' 24. Inside the Terminate procedure. (created by Visual Studio in step 1) add

' a call to RemoveContextMenu(). This will remove the Context menu when this .NET dll

' is unloaded. Before proceding to step 25 build and netload the dll. Right click

' on the ModelSpace background. You should see the new MenuItem. "Circle Jig"

 

 

' 25. Uncomment this to fix behavior where command line

' is not automatically set back to normal command after running

' the MenuItem.

' Imports System.Runtime.InteropServices '(move outside of the class needed for P/Invoke)

'acedPostCommand("CANCELCMD") ' Move this after CircleJig() in step 22

'<DllImport("acad.exe", CharSet:=CharSet.Unicode, EntryPoint:="?acedPostCommand@@YAHPB_W@Z")> _

'Public Shared Function acedPostCommand(ByVal cmd As String) As Boolean

'End Function

 

Adding a Page to the AutoCAD Options Dialog

 

In this section of the you will add a new User Control which can be displayed as a page on the AutoCAD Options dialog.  We can use this page to set default values for our application.  In this example it will simply be a string member variable. Note: Use these instructions to create the user control and then copy in the steps. Or you can use the Lab8 project that already has the user control and the steps.

 

Add a User Control to the project. Name it something like “myCustomTab”.  Add a Label and a TextBox so that it looks similar to the following:

 

 

Here are the steps for this section.

 

' Lab8 Steps 26 - 37. Add a tab to the Options dialog.

' To add a tab you need to subscribe to notifications when the options dialog

' is launched. This is done by passing the address of a member function to be called. 

' You will also need to implement the callback function; the second argument

' passed into the callback is a ‘TabbedDialogEventArgs’ object which we must

' use to call its ‘AddTab’ member. AddTab takes a title string, and an instance

' of a ‘TabbedDialogExtension’ object, which wraps our form.  Within the constructor

' of TabbedDialogExtension, we pass a new instance of our form, and callback

' addresses we can pass to handle either OnOK, OnCancel or OnHelp.

 

' 26. First Declare a Public Shared variable as a String. This variable will be set

' from our custom tab in the Options dialog. Name it something like "myVariable" 

 

' 27. Add a Publc Shared procedure called AddTabDialog. We will call this procedure

' from the Initialize() Sub that was created in step 1

' Note: Put the End Sub after step 28.

 

' 28. Use the AddHandler statement to had a Application DisplayingOptionDialog

' event. Use the DisplayingOptionDialog event of the Application class

' for the first parameter. For the second parameter (Delegate) use the

' AddressOf statement and the name of the procedure you will create in

' step 29. (name it TabHandler)

 

 

' 29. Create a Private Shared Sub named TabHandler. This is the Sub that

' will be called when the Options dialog is displayed. (The name needs to be

' the name used in the Delegate parameter of step 28). The first parameter is an

' object. (Use ByVal and sender as the name of the Object).

' The second parameter is a TabbedDialogEventArgs.

' (Use ByVal e As Autodesk.AutoCAD.ApplicationServices.TabbedDialogEventArgs)

' Note: Put the End Sub after step 33

 

 

' 30. Declare a variable as the user control that we are going to add to

' the Options dialog. (myCustomTab) Use the New keyword to instantiate it.

 

' 31. Delcare a variable as a TabbedDialogAction. Instantiate it using the New statement

' to create a new TabbedDialogAction for the parameter using AddressOf and the

' OnOk method of the User control variable from step 29.

' Note: The OnOk method will be added in Steps 35 - 36. (You can skip forward to these steps

' in the code window for the user form - myCustomTab - come back here of course)

 

' 32. Declare a variable as a TabbedDialogExtension. Instantiate it using the New statement

' to create a new TabbedDialogExtension for the control parameter pass in the User control variable

' from step 30. and the TabbedDialogAction pass in the variable from step 31.

 

' 33. Use the AddTab method of the TabbedDialogEventArgs passed into the event.

' (named e). For the Name parameter use something like  "Value for custom variable". For the

' TabbedDialogExtension parameter use the TabbedDialogExtension from step 32.

' Note: Proceed to step 34 in the TestTab function below.

 

 

' Run this command to get the value set from

<CommandMethod("testTab")> _

Public Sub TestTab()

    Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor

 

    ' 34. Uncomment this line to print the value set from the Tab added in the previous

    ' steps to the command line.

    ' Note: You may need to change myVariable to the name you used in step 26

    ' Proceed to steps 35 - 36 in the Code window for the UserControl. (myCustomTab)

    ' if you have not already done so. Also do step 37, close to step 23

    ' ed.WriteMessage(myVariable.ToString())

 

 

    ' After steps 35-36 are complete Build, Load and run the AutoCAD OPTIONS to see

    ' the custom dialog. Set the value in the text box click Ok and then run

    ' this command you should see the value set in the Options dialog printed

    ' on the command line.

    ' After this proceed to steps 38-46 in the code

    ' window for UserControl1. (Adds functionality for Drag & Drop).

 

End Sub

 

Copy these steps into the user control that will be shown in the Options dialog. (Needs to be inside the class).

 

' 35. Add a Public Sub named OnOk

' Note. Put the End Sub below step 36

 

 

' 36. Make the variable created in step 26 eqaul to 

' TextBox1.Text. Need to qualify the variable with the class name.

' something like:  adskClass.myVariable

 

' Run AutoCAD and open the OPTIONS dialog. You should see

' the new tab. Enter in some text in the TextBox and then

' click ok. Then run the testTab command. It should print

' the value you entered on the custom tab to the command line.

 

' Note: This is the end of the Custom Tab section of Lab8.

' Proceed to step 37 in the code window for UserControl1. In

' that section you will explore Drag & Drop from the PaletteSet

 

 

Add Drag and Drop support to the PaletteSet created in Lab3

 

In this section, we’ll add code which allows us to run a command when the user drags from the palette on to the AutoCAD editor. In order to support Drag and Drop, we first need an object to drag.  Add an additional ‘Label’ below the TreeView, named ‘DragLabel’.  From this label, we will be able to handle drag and drop into the AutoCAD editor. Here is a screenshot of the update to the user control. Note: you can update the project you have been working on or use the updated user control in the Lab8 project.   (It has the following steps).

 

 

To detect when a drag event is taking place, we need to know when certain mouse operations take place.  In the code window for the user control add the MouseMove event. Do this by selecting the Label and the event as in this screenshot:

 

 

 

 

Copy these steps 38-39 inside of the DragLabel_MouseMove Procedure.

 

' 38. It’s enough to see that we know when a mouse-move operation takes place.

' We can even go further to tell that the "left" mouse button is currently pressed

' Use an "If Then" statement for the test see if the Left mouse button is being

' used: System.Windows.Forms.Control.MouseButtons = System.Windows.Forms.MouseButtons.Left

' Put the "End If" beow step 39.

 

' 39. (Ensure a reference to Windowsbase has been added).

' This is needed for System.Windows.DependencyObject()

' Call the DoDragDrop method of the Application. For the drag source

' paramter use the "Me" keyword. For the data paramter use "Me" as well.

' For Allowed effects use System.Windows.Forms.DragDropEffects.All

' For the Target paramter use the New statement and a class named "MyDropTarget"

' This class is created in steps 40-46. The DropTarget is how our MyDropTarget

' override is hooked up to the mechanism.

 

 

Copy steps 40-46 to the code window of the user control.  A new class will be created.

 

' 40. Here we create a class that will detect when the object is "dropped"

' in the AutoCAD editor. Add a class to the project called MyDropTarget which

' Inherits from Autodesk.AutoCAD.Windows.DropTarget. (the name needs to be the

' same as used in step 39).

' Note: Put the "End Class" below in steps 46

 

' 41. Override the OnDrop procedure. (Use Public Overrides). For the parameter

' use "ByVal e As System.Windows.Forms.DragEventArgs"

 

' 42. Declare a variable as an Editor. Instantiate it by making it equal

' to Application.DocumentManager.MdiActiveDocument.Editor

 

' 43. Add a Try Catch block.

' Note: Put the Catch after step 45 and the End Try after step 46

 

' 44. Use the Using statement and declare a DocumentLock variable named

' docLock. Instantitate it using:

' Application.DocumentManager.MdiActiveDocument.LockDocument()

' Note: Put the "End Using" after step 45. Creating the variable will

' lock the document and unlock it.

 

' 45. Run the AddAnEnt procedure from lab 4. Need to

' qualify the name with the Class. (adskClass.AddAnEnt())

 

 

' 46. add ex as System.Exception to the Catch statement

' Use the Editor created in step 42 to display message to the

' user. If we get here something went wrong. Use something like

' this for the message parameter:

' "Error Handling OnDrop: " + ex.Message

 

' Note this is the End of Lab8. Run AutoCAD load the dll and run the

' Palette command. Drag the label to the drawing area. The AddAnEnd command

' should start when you drop it.

 

This is the End of Lab8

gist.github.com

GitHubGist クラス

VBAでクラス使うなら.NETにしたほうがいいんじゃない?

1回目の.NET挑戦では、デバッグ時にいちいちCADを立ち上げる、netloadする。修正したらまた立ち上げ直してnetload・・・この手順がめんどくさすぎてあきらめました。

その間にVBAの腕も上がり、コードの改善もできました。

今回2回目の挑戦でーす。がんばれー!

他の業務はVBAで進めなくてはいけなくて大変だけどね!

がんばるのだぞ!

 

 

ProBuilder PolyBrush

胆石・・・石より小さくて泥なので胆泥と言われたのは、かれこれ5年ほど前。

石ならばレーザーをあてて割ってしまうなどできるのだが。

体質のせいだろう、コレステロールの泥が出来続ける。

量が増えるかうまく流れないときは棒がつっかかったように感じ

とにかく寝てしまう。膨満感このうえなく、肝臓か胆のうが脳を乗っ取って

「とにかく寝ろ!」と指令を出してくるのである。

 

 

そんなことより!今日の一押しはこちら。

 

www.slideshare.net

 

 

 

 

blogs.unity3d.com

 

ProBuilderのNewShapeは問題ないが、NewPolyShapeで作成したオブジェクトは

私の貧PCでは真っ黒な物体となり、CPUが100%となり、レンダリングが終了するのにはおよそ1時間ほどかかりました。

はやく新しいPC買いたい!!!!!!!!!!!!!

 

昨日書いたOnDrawGizmos()のScriptがAR実行にて機能しなかったので、開いてOnDrawGizmosSelected()にするところVisualStudio2017にて

”ソリューションを準備しています”のまま、、、、一晩明けても。www

 

 

 

 

遅れ気味ですがこれも!なんせ今年の10月からUmity始めたばかりなのでいろいろ。

 

 

blogs.unity3d.com

 

 

げげ!動画56分もあるよ

X=1073 Y=600 のやつ、やっぱり英語のほうだった。そして何故か iOs 

using UnityEngine;
using System.Collections;
using UnityEngine.iOS;

// Input.GetTouch example. // // Attach to an origin based cube. // A screen touch moves the cube on an iPhone or iPad. // A second screen touch reduces the cube size.

public class ExampleClass : MonoBehaviour { private Vector3 position; private float width; private float height;

void Awake() { width = (float)Screen.width / 2.0f; height = (float)Screen.height / 2.0f;

// Position used for the cube. position = new Vector3(0.0f, 0.0f, 0.0f); }

void OnGUI() { // Compute a fontSize based on the size of the screen width. GUI.skin.label.fontSize = (int)(Screen.width / 25.0f);

GUI.Label(new Rect(20, 20, width, height * 0.25f), "x = " + position.x.ToString("f2") + ", y = " + position.y.ToString("f2")); }

void Update() { // Handle screen touches. if (Input.touchCount > 0) { Touch touch = Input.GetTouch(0);

// Move the cube if the screen has the finger moving. if (touch.phase == TouchPhase.Moved) { Vector2 pos = touch.position; pos.x = (pos.x - width) / width; pos.y = (pos.y - height) / height; position = new Vector3(-pos.x, pos.y, 0.0f);

// Position the cube. transform.position = position; }

if (Input.touchCount == 2) { touch = Input.GetTouch(1);

if (touch.phase == TouchPhase.Began) { // Halve the size of the cube. transform.localScale = new Vector3(0.75f, 0.75f, 0.75f); }

if (touch.phase == TouchPhase.Ended) { // Restore the regular size of the cube. transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); } } } } }

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour { public GameObject particle; void Update() { for (int i = 0; i < Input.touchCount; ++i) { if (Input.GetTouch(i).phase == TouchPhase.Began) { // Construct a ray from the current touch coordinates Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position); // Create a particle if hit if (Physics.Raycast(ray)) Instantiate(particle, transform.position, transform.rotation); } } } }
using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour { public GameObject particle; void Update() { for (int i = 0; i < Input.touchCount; ++i) { if (Input.GetTouch(i).phase == TouchPhase.Began) { // Construct a ray from the current touch coordinates Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position); // Create a particle if hit if (Physics.Raycast(ray)) Instantiate(particle, transform.position, transform.rotation); } } } }

Input.GetTouch  英語と日本語Exampleが違うのかな?

Input.GetTouch

 
 Leave feedback
 
 
public static Touch GetTouch(int index);

Parameters

index The touch input on the device screen.

Returns

Touch Touch details in the struct.

Description

Call Input.GetTouch to obtain a Touch struct.

Input.GetTouch returns Touch for a selected screen touch (for example, from a finger or stylus). Touch describes the screen touch. The index argument selects the screen touch.

Input.touchCount provides the current number of screen touches. If Input.touchCount is greater than zero, the GetTouch index sets which screen touch to check. Touch returns a struct with the screen touch details. Each extra screen touch uses an increasing Input.touchCount.

GetTouch returns a Touch struct. Use zero to obtain the first screen touch. As an example, Touch includes position in pixels.

No temporary variables are allocated.

 

 






using UnityEngine; using System.Collections; using UnityEngine.iOS;

// Input.GetTouch example. // // Attach to an origin based cube. // A screen touch moves the cube on an iPhone or iPad. // A second screen touch reduces the cube size.

public class ExampleClass : MonoBehaviour { private Vector3 position; private float width; private float height;

void Awake() { width = (float)Screen.width / 2.0f; height = (float)Screen.height / 2.0f;

// Position used for the cube. position = new Vector3(0.0f, 0.0f, 0.0f); }

void OnGUI() { // Compute a fontSize based on the size of the screen width. GUI.skin.label.fontSize = (int)(Screen.width / 25.0f);

GUI.Label(new Rect(20, 20, width, height * 0.25f), "x = " + position.x.ToString("f2") + ", y = " + position.y.ToString("f2")); }

void Update() { // Handle screen touches. if (Input.touchCount > 0) { Touch touch = Input.GetTouch(0);

// Move the cube if the screen has the finger moving. if (touch.phase == TouchPhase.Moved) { Vector2 pos = touch.position; pos.x = (pos.x - width) / width; pos.y = (pos.y - height) / height; position = new Vector3(-pos.x, pos.y, 0.0f);

// Position the cube. transform.position = position; }

if (Input.touchCount == 2) { touch = Input.GetTouch(1);

if (touch.phase == TouchPhase.Began) { // Halve the size of the cube. transform.localScale = new Vector3(0.75f, 0.75f, 0.75f); }

if (touch.phase == TouchPhase.Ended) { // Restore the regular size of the cube. transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); } } } } }






A second example:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour { public GameObject projectile; public GameObject clone;

void Update() { for (int i = 0; i < Input.touchCount; ++i) { if (Input.GetTouch(i).phase == TouchPhase.Began) { clone = Instantiate(projectile, transform.position, transform.rotation) as GameObject; } } } }
 

A third example:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour { public GameObject particle; void Update() { for (int i = 0; i < Input.touchCount; ++i) { if (Input.GetTouch(i).phase == TouchPhase.Began) { // Construct a ray from the current touch coordinates Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);

// Create a particle if hit if (Physics.Raycast(ray)) { Instantiate(particle, transform.position, transform.rotation); } } } } }
 

Input.GetTouch  クローンがかわいくできたけど 本当はRayを飛ばしたい

Input.GetTouch

 
 
 
public static Touch GetTouch (int index);

説明

特定のタッチ状態を表すオブジェクトを返します(一時的な変数は割り当てられません)

GetTouch returns a Touch struct. As an example the Touch returned with the pressure.

 

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour { public float speed = 0.1F; void Update() { if (Input.touchCount > 0 &amp;&amp; Input.GetTouch(0).phase == TouchPhase.Moved) { // Get movement of the finger since last frame Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;

// Move object across XY plane transform.Translate(-touchDeltaPosition.x * speed, -touchDeltaPosition.y * speed, 0); } } }



using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour { public GameObject projectile; public GameObject clone; void Update() { for (int i = 0; i < Input.touchCount; ++i) { if (Input.GetTouch(i).phase == TouchPhase.Began) clone = Instantiate(projectile, transform.position, transform.rotation) as GameObject; } } }



using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour { public GameObject particle; void Update() { for (int i = 0; i < Input.touchCount; ++i) { if (Input.GetTouch(i).phase == TouchPhase.Began) { // Construct a ray from the current touch coordinates Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position); // Create a particle if hit if (Physics.Raycast(ray)) Instantiate(particle, transform.position, transform.rotation); } } } }