PDA

View Full Version : Maxscripting the Graphite Module


Baltazaar
07-29-2009, 11:10 AM
I'm having a discussion with myself in this post: http://forums.cgsociety.org/showthread.php?t=788490
Is it possible to use Maxscript to create a new GUI with select components from the Graphite Modeling module??

PEN
07-29-2009, 12:33 PM
I see zero in the help file but from what I understand it is all XML based, if that is the case and you can sort out how it if formatted then you can easily set up your own.

Baltazaar
07-29-2009, 01:06 PM
Well, I'm pretty competent in XML, and I program in Python and C (and C#, Lisp), so there should be some good XML modules that can help me sort this out.

Thanks.

PEN
07-29-2009, 01:26 PM
Let us know what you find as I don't think that many of us have dived into it at this point.

scrimski
07-29-2009, 01:55 PM
+1.
Would be nice to have this in a wiki somewhere (hinthint (http://wiki.cgsociety.org/index.php/Main_Page)).

Baltazaar
07-29-2009, 09:37 PM
For the time being I think the C++ API is the solution...

I'll check it out and keep posting.

denisT
07-29-2009, 11:03 PM
Is it possible to use Maxscript to create a new GUI with select components from the Graphite Modeling module??

I don't really understand what you want to do. Delete useless buttons from Ribbon? Use Graphite's functions in your own GUI? Create you own "looking like Ribbon" GUIs? Add new GUI elements to Ribbon?
First and Second are possible. Third is probably not. Forth is probably possible...

denisT
07-30-2009, 04:06 AM
today I've played half a day with Graphite and Ribbon in max 2010 and I'm 100% sure that:
1. You can call all Graphite functions from MAXScript
2. You can create a shortcut to any function of Graphite
3. You can remove any control from Ribbon control including whole Tab
4. You can completely redesign Ribbon control (change icons, tooltips, labels, positions, and size of controls, etc.)
4. You can change any execution of any Ribbon control
5. You can add your own controls with your own functions to Ribbon control
6. You can't create workable in MAX your own ribbon control
7. You don't have to use c++ and MAX SDK to do ... (see above)
8. You can but don't have to extend Graphite and Ribbon functionality using c#


PS. ... and honestly I've looked at the source codes and was not impressed... I think that would be better to fix old bugs then create new nice looking skin for Editable_Poly interface.

Baltazaar
07-30-2009, 07:33 AM
8. You can but don't have to extend Graphite and Ribbon functionality using c#


PS. ... and honestly I've looked at the source codes and was not impressed... I think that would be better to fix old bugs then create new nice looking skin for Editable_Poly interface.

You're talking about C++ right, not C#?

Well, I have gotten that much out of the interface myself. So, if you don't need your own custom GUI, you can stick to the old ways of creating launchers, keyboard shortcuts etc.

Everyone: Thanks for your replies, I'm not going to investigate the C++ API for this matter.

Though I found some interesting stuff regarding the new MentalRay and MentalMill using C++, but, that is a whole other story.

PEN
07-30-2009, 02:41 PM
I don't know if you are up for it Denis but I'm sure people here would love to see some Max script code that does some of this. Might get others started on rebuilding it the way that they like.

martroyx
08-01-2009, 11:31 AM
Might get others started on rebuilding it the way that they like.

well, I totally agree Paul !

here's how to execute function from the ribbon, but since I don't use the thing, I'll just let the task of reconstructing it to someone else :-)


---ribbon=DotnetObject "MaxWpfContent.MaxModelingRibbonUserControl"
--ribbon.LoadRibbon()

--dotnet.loadassembly "$Max\\bin\assemblies\\MaxWpfContent.dll"
---dotnet.showConstructors "ManagedServices.MaxActionItem"
--NewActionItem=DotnetObject "ManagedServices.MaxActionItem" <ActionItem*>aActionItem

-- .[static]<ManagedServices.MaxActionItem>ResolveMacroItem <System.String>aMacroName <System.String>aMacroCategory
--- .[static]<ManagedServices.MaxActionItem>ResolveNativeItem <System.UInt32>aActionID <System.UInt32>aTableID
-- .[static]<ManagedServices.MaxActionItem>ResolveNativeItem <System.String>aActionName <System.String>aGroupName

--//--
(
dotnet.loadassembly "$Max\\ManagedServices.dll"
--//--
ActionItemResolver=Dotnetclass "ManagedServices.MaxActionItemResolver"
NewItem=ActionItemResolver.ResolveMacroItem "Convert_to_Poly" "Modifier Stack"
NewItem.Execute()
)
--//--



Best regard,
Martin

martroyx
08-01-2009, 04:46 PM
well, I come up with this to filter the xaml file, but that not very nice ... does anyone know of a better way ? :-)


(
xaml_file=openfile(getdir #ui + "\\Ribbon\\ModelingRibbon.xaml")
out_to_file=newscript()
--//--
while not eof xaml_file do
(
Compare=dotnetobject "system.string" (readline xaml_file)
--//--
if Compare.contains "MaxMacroRibbonButton" then
(
idx_name=Compare.LastIndexOf "MacroName="
idx_macro=Compare.LastIndexOf "MacroCategory="
c_name=((dotnetobject "system.string" (Compare.Substring (idx_macro+15))).split "\"")[1]
str_name=Compare.Substring (idx_name+11) (idx_macro-idx_name-13)
--//--
try(format ("\""+str_name+"\" \""+c_name+"\"\n") to:out_to_file)catch()
)
--//--
)
--//--
close xaml_file
)

denisT
08-01-2009, 05:02 PM
well, I come up with this to filter the xaml file, but that not very nice ... does anyone know of a better way ? :-)

Youíre right. This is not the way. I can parse the xaml and technically can change any control settings, save and reload Ribbon. New changes will appear. But what is the use? I want to do it on fly... I need only one thing - pointer to the MAX Ribbon control. And unfortunately canít find a way to get it using MXS. But Iím keep digging...

fn parseXAML file: =
(
if file == unsupplied do file = (getDir #ui + "Ribbon\\ModelingRibbon.xaml")
mReader = dotnetobject "System.Windows.Markup.XamlReader"
xReader = dotnetclass "System.Xml.XmlReader"
xReader = xReader.create file
mReader.load xReader
)

returns Ribbon Control with default MAX setting

martroyx
08-01-2009, 05:11 PM
so what you want it to add button to the existing toolbar if I understand well ?

we can call of the function of the ribbon , so just throw that away an put this in a toolbar
or something ...why do we need pointer to the existing one ?

edit : thank for the reader may come andy :thumbsup:

edit2 : ok now, I understand what you want , I'll check this out too !

Martin

denisT
08-01-2009, 05:16 PM
so what you want it to add button to the existing toolbar if I understand well ?

we can call of the function of the ribbon , so just throw that away an put this in a toolbar
or something ...why do we need pointer to the existing one ?

Martin

I can edit xaml using Microsoft Visual 2008. It's WPF client. And it was made as WPF client. Add or remove anything is not a problem. I want to add my elements without changes in the original xaml.

denisT
08-01-2009, 05:21 PM
so what you want it to add button to the existing toolbar if I understand well ?

we can call of the function of the ribbon , so just throw that away an put this in a toolbar
or something ...why do we need pointer to the existing one ?

edit : thank for the reader may come andy :thumbsup:

edit2 : ok now, I understand what you want , I'll check this out too !

Martin

if you need all macros, functions, structures, and etc. used by Graphite you can find them in Macro_PolyTools.mcr, Macro_Ribbon-Modeling.mcr, Ribbon-Modeling.ms... and global PolyBoost scructure.

martroyx
08-01-2009, 06:19 PM
Youíre right. This is not the way. I can parse the xaml and technically can change any control settings, save and reload Ribbon. New changes will appear. But what is the use? I want to do it on fly... I need only one thing - pointer to the MAX Ribbon control. And unfortunately canít find a way to get it using MXS. But Iím keep digging...




is it the pointer youre looking for ?

denisT
08-01-2009, 06:23 PM
is it the pointer youre looking for ?'

:) no... this is graphite window's handle. Ribbon Control is a child of this window but Spy doesn't see it for some reason.

martroyx
08-01-2009, 06:29 PM
ok then I'll dig some more :rolleyes:...once you get that pointer what can you do with it from maxscript ?

denisT
08-01-2009, 06:35 PM
ok then I'll dig some more :rolleyes:...once you get that pointer what can you do with it from maxscript ?

Technically the Ribbon Control is kinda .NET control and Control.FromHandle has to return me the object (hopefully). After that I will do with it anything and everything! :)

martroyx
08-01-2009, 06:39 PM
ok, that what I wanted to hear , I like .Net :-) ... do you know the object that created the original so that I can start looking at the right place ?

edit : I think it's in autodesk.windows namespace but can remember ?

denisT
08-01-2009, 06:44 PM
ok, that what I wanted to hear , I like .Net :-) ... do you know the object that created the original so that I can start looking at the right place ?

sorry... I missed the point. what is your question? I know properties, methods, and constructors of Ribbon Control and other controls used by Ribbon. I can create MAX Ribbon Control and get all info that I need.

martroyx
08-01-2009, 06:48 PM
ho sorry for by bad english , I mean the ribbon constructor ??

edit : nevermind , I found it ...I'll check this out ....dont know if it possible throught :-(

denisT
08-01-2009, 07:14 PM
ho sorry for by bad english , I mean the ribbon constructor ??

edit : nevermind , I found it ...I'll check this out ....dont know if it possible throught :-(

MaxRibbonControl has only one simple constructor. Looks like the control can't be added to any .NET control without c#ing. I couldn't find a way. But the creating of MaxRibbonControl(s) is not my goal. Honestly I don't like Ribbon. I want to get access to its resources, elements.

martroyx
08-01-2009, 09:43 PM
in fact, I think it's the right pointer because if you send close to it , it close the ribbon not the docking frame , I think it something else that prevent acess , what do you think ?

edit : how do you know that it's not the ribbon, it seam like the ribbon to me !!

denisT
08-01-2009, 09:58 PM
in fact, I think it's the right pointer because if you send close to it , it close the ribbon not the docking frame , I think it something else that prevent acess , what do you think ?

I think that Graphite Tool is shoddy...

martroyx
08-01-2009, 10:44 PM
shoddy... ???

ho, and I wonder if it have something to do but there's another docking panel hided below the big green button it it's called Graphite modeling tools (vertical) ...

>why they did not create it on the fly like any other panel ... maybe it need to be there because they can't recreate the ribbon once max is started ??

>ok, you where right , that was not the ribbon:banghead:

martroyx
08-02-2009, 04:34 PM
after I played with this ribbon a bit more , I'm able to tell you more about it :

1:your not going to find your pointer from maxscript , unless autodesk put a nice function to do so!

2:we can create the ribbon from maxscript :eek:

I'm still not sure how all of this is working, I've got some trouble finding how to add the button , that's the first time I play with wpf stuff .....here what I got so far....


(
--dotnet.loadassembly "$Max\\bin\assemblies\\MaxWpfContent.dll"
--dotnet.loadassembly "$Max\\AdWindows.dll"
--//--
FloatingFrame=dotnetobject "Autodesk.Internal.Windows.FloatingFrame"
RibbonPanelControl=dotnetobject "Autodesk.Private.Windows.RibbonPanelControl"
RibbonPanel=dotnetobject "Autodesk.Windows.RibbonPanel"
RibbonPanelSource=dotnetobject "Autodesk.Windows.RibbonPanelSource"
RibbonButton=dotnetobject "Autodesk.Windows.RibbonButton"
--//--
RibbonPanelSource.Title="MarTroYx Ribbon Test"
--//--
FloatingFrame.Content=RibbonPanelControl
RibbonPanelControl.Panel=RibbonPanel
RibbonPanel.Source=RibbonPanelSource
--//--
FloatingFrame.topmost=true
FloatingFrame.Show()
)


fell free to correct me if I'm wrong of course !
Martin

martroyx
08-20-2009, 10:19 AM
maybe a bit late but that's the max ribbon object...


ComponentManager=dotnetclass "Autodesk.Windows.ComponentManager"
MaxRibbon=ComponentManager.Ribbon


seam to lose ref to the current one if we create new one, so you may need to restart :).

regard,
Martin

PEN
08-20-2009, 01:16 PM
Well this is all looking hopeful, I'm not sure what I would want to do with it yet but it is always good to know what can be done.

Thanks guys for doing this leg work, I just don't have time for this sort of thing these days.

cyfer
08-20-2009, 03:22 PM
maybe a bit late but that's the max ribbon object...


ComponentManager=dotnetclass "Autodesk.Windows.ComponentManager"
MaxRibbon=ComponentManager.Ribbon


seam to lose ref to the current one if we create new one, so you may need to restart :).

regard,
Martin

I assume you're doing that on 64bit , cause this code and the one you posted earlier (post 28) doesn't work on 32 bit

the code in your earlier post gives me the glorious message
-- Runtime error: dotNet runtime exception: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

the same thing occured in my attempts to instanciate a wpf window or any framework 3 object in 32bit max !

martroyx
08-20-2009, 09:58 PM
Hi cyfer,

Ho well, yes I didn't tested it under 32bit that's true :-)
so , I think I found the solution ...you simply need to collect the garbage :-)


(
ComponentManager=dotnetclass "Autodesk.Windows.ComponentManager"
ComponentManager.Ribbon.Tabs.Clear()
--//--
Mx_Tab=dotnetobject "Autodesk.Windows.RibbonTab"
Mx_Tab.Title="Test Martin"
--//--
Mx_Panel=dotnetobject "Autodesk.Windows.RibbonPanel"
--//--
RibbonPanelSource=dotnetobject "Autodesk.Windows.RibbonPanelSource"
--//--
Mx_Button1=dotnetobject "Autodesk.Windows.RibbonButton"
Mx_Button1.Text="1"
Mx_Button1.showtext=true
--//--
Mx_Button2=dotnetobject "Autodesk.Windows.RibbonButton"
Mx_Button2.Text="2"
Mx_Button2.showtext=true
--//--
Mx_Button3=dotnetobject "Autodesk.Windows.RibbonButton"
Mx_Button3.Text="3"
Mx_Button3.showtext=true
--//--
Mx_Button4=dotnetobject "Autodesk.Windows.RibbonButton"
Mx_Button4.Text="4"
Mx_Button4.showtext=true
--//--
ComponentManager.Ribbon.Tabs.Add(Mx_Tab)
Mx_Panel.Source=RibbonPanelSource
RibbonPanelSource.items.add(Mx_Button1)
RibbonPanelSource.items.add(Mx_Button2)
RibbonPanelSource.items.add(Mx_Button3)
RibbonPanelSource.items.add(Mx_Button4)
Mx_Tab.Panels.Add(Mx_Panel)
--//--
ComponentManager=undefined
(dotnetclass "System.gc").collect()
gc() ---just to make sure :-)
)



edit: in fact I think that it's the maxscript gc needed here, if I remove it , it crash when touching the ribbon !!

can you please confirm that it's working ...maybe I got something else that make
it work who know :-)

regard,
Martin

cyfer
08-21-2009, 01:01 AM
yes , it worked ! , lost the original ribbon but it worked :thumbsup:

when i removed the garbage collection ... i got the crash
the maxscript GC does nothing btw

well , another crash with the dot.net garbage colection only ..LOL

and here comes the third crash with garbage collection form mxs and .net

i actually don't need this ribbon shit :hmm:

i've extracted the whole functions and the macroscripts of the ribbon from the macrofiles that come with the ribbon sometime ago

i can run them all using a ExcuteMaxScriptCommand from inside a C# dll
i stopped for now cause i couldn't find a suitable easy ...fast ... etc layout for all of those
once i get a decent idea ... bye bye ribbon for good

martroyx
08-21-2009, 01:13 AM
hehe it not that bad ..it work well on my test here just need to make sure componentmanager is collected by maxscript gc ...I dont need the function from the ribbon I just want to use the frame to dock some other tool :-)

martroyx
08-21-2009, 01:33 AM
I'm under xp64 through ...maybe it don't work in a 32bit os ... but can't test it for now !!

edit : ho, make sure you execute in local scope too :-)

CGTalk Moderation
08-21-2009, 01:33 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.