space_view3d.py 215 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. # <pep8 compliant>
  19. import bpy
  20. from bpy.types import (
  21. Header,
  22. Menu,
  23. Panel,
  24. )
  25. from bl_ui.properties_paint_common import (
  26. UnifiedPaintPanel,
  27. )
  28. from bl_ui.properties_grease_pencil_common import (
  29. AnnotationDataPanel,
  30. AnnotationOnionSkin,
  31. GreasePencilMaterialsPanel,
  32. )
  33. from bl_ui.space_toolsystem_common import (
  34. ToolActivePanelHelper,
  35. )
  36. from bpy.app.translations import contexts as i18n_contexts
  37. class VIEW3D_HT_tool_header(Header):
  38. bl_space_type = 'VIEW_3D'
  39. bl_region_type = 'TOOL_HEADER'
  40. def draw(self, context):
  41. layout = self.layout
  42. layout.row(align=True).template_header()
  43. self.draw_tool_settings(context)
  44. layout.separator_spacer()
  45. VIEW3D_HT_header.draw_xform_template(layout, context)
  46. layout.separator_spacer()
  47. self.draw_mode_settings(context)
  48. def draw_tool_settings(self, context):
  49. layout = self.layout
  50. tool_mode = context.mode
  51. # Active Tool
  52. # -----------
  53. from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
  54. tool = ToolSelectPanelHelper.draw_active_tool_header(
  55. context, layout,
  56. tool_key=('VIEW_3D', tool_mode),
  57. )
  58. # Object Mode Options
  59. # -------------------
  60. # Example of how tool_settings can be accessed as pop-overs.
  61. # TODO(campbell): editing options should be after active tool options
  62. # (obviously separated for from the users POV)
  63. draw_fn = getattr(_draw_tool_settings_context_mode, tool_mode, None)
  64. if draw_fn is not None:
  65. draw_fn(context, layout, tool)
  66. popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"}
  67. # Note: general mode options should be added to 'draw_mode_settings'.
  68. if tool_mode == 'SCULPT':
  69. if (tool is not None) and tool.has_datablock:
  70. layout.popover_group(context=".paint_common", **popover_kw)
  71. elif tool_mode == 'PAINT_VERTEX':
  72. if (tool is not None) and tool.has_datablock:
  73. layout.popover_group(context=".paint_common", **popover_kw)
  74. elif tool_mode == 'PAINT_WEIGHT':
  75. if (tool is not None) and tool.has_datablock:
  76. layout.popover_group(context=".paint_common", **popover_kw)
  77. elif tool_mode == 'PAINT_TEXTURE':
  78. if (tool is not None) and tool.has_datablock:
  79. layout.popover_group(context=".paint_common", **popover_kw)
  80. elif tool_mode == 'EDIT_ARMATURE':
  81. pass
  82. elif tool_mode == 'EDIT_CURVE':
  83. pass
  84. elif tool_mode == 'EDIT_MESH':
  85. pass
  86. elif tool_mode == 'POSE':
  87. pass
  88. elif tool_mode == 'PARTICLE':
  89. # Disable, only shows "Brush" panel, which is already in the top-bar.
  90. # if tool.has_datablock:
  91. # layout.popover_group(context=".paint_common", **popover_kw)
  92. pass
  93. elif tool_mode == 'PAINT_GPENCIL':
  94. if (tool is not None) and tool.has_datablock:
  95. layout.popover_group(context=".greasepencil_paint", **popover_kw)
  96. elif tool_mode == 'SCULPT_GPENCIL':
  97. layout.popover_group(context=".greasepencil_sculpt", **popover_kw)
  98. elif tool_mode == 'WEIGHT_GPENCIL':
  99. layout.popover_group(context=".greasepencil_weight", **popover_kw)
  100. def draw_mode_settings(self, context):
  101. layout = self.layout
  102. mode_string = context.mode
  103. def row_for_mirror():
  104. row = layout.row(align=True)
  105. row.label(icon='MOD_MIRROR')
  106. sub = row.row(align=True)
  107. sub.scale_x = 0.6
  108. return row, sub
  109. if mode_string == 'EDIT_MESH':
  110. _row, sub = row_for_mirror()
  111. sub.prop(context.object.data, "use_mirror_x", text="X", toggle=True)
  112. tool_settings = context.tool_settings
  113. layout.prop(tool_settings, "use_mesh_automerge", text="")
  114. elif mode_string == 'EDIT_ARMATURE':
  115. _row, sub = row_for_mirror()
  116. sub.prop(context.object.data, "use_mirror_x", text="X", toggle=True)
  117. elif mode_string == 'POSE':
  118. _row, sub = row_for_mirror()
  119. sub.prop(context.object.pose, "use_mirror_x", text="X", toggle=True)
  120. elif mode_string == 'PAINT_WEIGHT':
  121. row, sub = row_for_mirror()
  122. sub.prop(context.object.data, "use_mirror_x", text="X", toggle=True)
  123. row.popover(panel="VIEW3D_PT_tools_weightpaint_symmetry_for_topbar", text="")
  124. elif mode_string == 'SCULPT':
  125. row, sub = row_for_mirror()
  126. sculpt = context.tool_settings.sculpt
  127. sub.prop(sculpt, "use_symmetry_x", text="X", toggle=True)
  128. sub.prop(sculpt, "use_symmetry_y", text="Y", toggle=True)
  129. sub.prop(sculpt, "use_symmetry_z", text="Z", toggle=True)
  130. row.popover(panel="VIEW3D_PT_sculpt_symmetry_for_topbar", text="")
  131. elif mode_string == 'PAINT_TEXTURE':
  132. _row, sub = row_for_mirror()
  133. ipaint = context.tool_settings.image_paint
  134. sub.prop(ipaint, "use_symmetry_x", text="X", toggle=True)
  135. sub.prop(ipaint, "use_symmetry_y", text="Y", toggle=True)
  136. sub.prop(ipaint, "use_symmetry_z", text="Z", toggle=True)
  137. # No need for a popover, the panel only has these options.
  138. elif mode_string == 'PAINT_VERTEX':
  139. row, sub = row_for_mirror()
  140. vpaint = context.tool_settings.vertex_paint
  141. sub.prop(vpaint, "use_symmetry_x", text="X", toggle=True)
  142. sub.prop(vpaint, "use_symmetry_y", text="Y", toggle=True)
  143. sub.prop(vpaint, "use_symmetry_z", text="Z", toggle=True)
  144. row.popover(panel="VIEW3D_PT_tools_vertexpaint_symmetry_for_topbar", text="")
  145. # Expand panels from the side-bar as popovers.
  146. popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"}
  147. if mode_string == 'SCULPT':
  148. layout.popover_group(context=".sculpt_mode", **popover_kw)
  149. elif mode_string == 'PAINT_VERTEX':
  150. layout.popover_group(context=".vertexpaint", **popover_kw)
  151. elif mode_string == 'PAINT_WEIGHT':
  152. layout.popover_group(context=".weightpaint", **popover_kw)
  153. elif mode_string == 'PAINT_TEXTURE':
  154. layout.popover_group(context=".imagepaint", **popover_kw)
  155. elif mode_string == 'EDIT_TEXT':
  156. layout.popover_group(context=".text_edit", **popover_kw)
  157. elif mode_string == 'EDIT_ARMATURE':
  158. layout.popover_group(context=".armature_edit", **popover_kw)
  159. elif mode_string == 'EDIT_METABALL':
  160. layout.popover_group(context=".mball_edit", **popover_kw)
  161. elif mode_string == 'EDIT_LATTICE':
  162. layout.popover_group(context=".lattice_edit", **popover_kw)
  163. elif mode_string == 'EDIT_CURVE':
  164. layout.popover_group(context=".curve_edit", **popover_kw)
  165. elif mode_string == 'EDIT_MESH':
  166. layout.popover_group(context=".mesh_edit", **popover_kw)
  167. elif mode_string == 'POSE':
  168. layout.popover_group(context=".posemode", **popover_kw)
  169. elif mode_string == 'PARTICLE':
  170. layout.popover_group(context=".particlemode", **popover_kw)
  171. elif mode_string == 'OBJECT':
  172. layout.popover_group(context=".objectmode", **popover_kw)
  173. elif mode_string in {'PAINT_GPENCIL', 'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}:
  174. # Grease pencil layer.
  175. gpl = context.active_gpencil_layer
  176. if gpl and gpl.info is not None:
  177. text = gpl.info
  178. maxw = 25
  179. if len(text) > maxw:
  180. text = text[:maxw - 5] + '..' + text[-3:]
  181. else:
  182. text = ""
  183. layout.label(text="Layer:")
  184. sub = layout.row()
  185. sub.ui_units_x = 8
  186. sub.popover(
  187. panel="TOPBAR_PT_gpencil_layers",
  188. text=text,
  189. )
  190. class _draw_tool_settings_context_mode:
  191. @staticmethod
  192. def SCULPT(context, layout, tool):
  193. if (tool is None) or (not tool.has_datablock):
  194. return
  195. paint = context.tool_settings.sculpt
  196. layout.template_ID_preview(paint, "brush", rows=3, cols=8, hide_buttons=True)
  197. brush = paint.brush
  198. if brush is None:
  199. return
  200. from bl_ui.properties_paint_common import (
  201. brush_basic_sculpt_settings,
  202. )
  203. brush_basic_sculpt_settings(layout, context, brush, compact=True)
  204. @staticmethod
  205. def PAINT_TEXTURE(context, layout, tool):
  206. if (tool is None) or (not tool.has_datablock):
  207. return
  208. paint = context.tool_settings.image_paint
  209. layout.template_ID_preview(paint, "brush", rows=3, cols=8, hide_buttons=True)
  210. brush = paint.brush
  211. if brush is None:
  212. return
  213. from bl_ui.properties_paint_common import (
  214. UnifiedPaintPanel,
  215. brush_basic_texpaint_settings,
  216. )
  217. capabilities = brush.image_paint_capabilities
  218. if capabilities.has_color:
  219. UnifiedPaintPanel.prop_unified_color(layout, context, brush, "color", text="")
  220. brush_basic_texpaint_settings(layout, context, brush, compact=True)
  221. @staticmethod
  222. def PAINT_VERTEX(context, layout, tool):
  223. if (tool is None) or (not tool.has_datablock):
  224. return
  225. paint = context.tool_settings.vertex_paint
  226. layout.template_ID_preview(paint, "brush", rows=3, cols=8, hide_buttons=True)
  227. brush = paint.brush
  228. if brush is None:
  229. return
  230. from bl_ui.properties_paint_common import (
  231. UnifiedPaintPanel,
  232. brush_basic_vpaint_settings,
  233. )
  234. capabilities = brush.vertex_paint_capabilities
  235. if capabilities.has_color:
  236. UnifiedPaintPanel.prop_unified_color(layout, context, brush, "color", text="")
  237. brush_basic_vpaint_settings(layout, context, brush, compact=True)
  238. @staticmethod
  239. def PAINT_WEIGHT(context, layout, tool):
  240. if (tool is None) or (not tool.has_datablock):
  241. return
  242. paint = context.tool_settings.weight_paint
  243. layout.template_ID_preview(paint, "brush", rows=3, cols=8, hide_buttons=True)
  244. brush = paint.brush
  245. if brush is None:
  246. return
  247. from bl_ui.properties_paint_common import brush_basic_wpaint_settings
  248. brush_basic_wpaint_settings(layout, context, brush, compact=True)
  249. @staticmethod
  250. def PAINT_GPENCIL(context, layout, tool):
  251. if tool is None:
  252. return
  253. # is_paint = True
  254. # FIXME: tools must use their own UI drawing!
  255. if tool.idname in {"builtin.line", "builtin.box", "builtin.circle", "builtin.arc", "builtin.curve"}:
  256. # is_paint = False
  257. pass
  258. elif tool.idname == "Cutter":
  259. row = layout.row(align=True)
  260. row.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold")
  261. return
  262. elif not tool.has_datablock:
  263. return
  264. paint = context.tool_settings.gpencil_paint
  265. brush = paint.brush
  266. if brush is None:
  267. return
  268. gp_settings = brush.gpencil_settings
  269. def draw_color_selector():
  270. ma = gp_settings.material
  271. row = layout.row(align=True)
  272. if not gp_settings.use_material_pin:
  273. ma = context.object.active_material
  274. icon_id = 0
  275. if ma:
  276. icon_id = ma.id_data.preview.icon_id
  277. txt_ma = ma.name
  278. maxw = 25
  279. if len(txt_ma) > maxw:
  280. txt_ma = txt_ma[:maxw - 5] + '..' + txt_ma[-3:]
  281. else:
  282. txt_ma = ""
  283. sub = row.row()
  284. sub.ui_units_x = 8
  285. sub.popover(
  286. panel="TOPBAR_PT_gpencil_materials",
  287. text=txt_ma,
  288. icon_value=icon_id,
  289. )
  290. row.prop(gp_settings, "use_material_pin", text="")
  291. row = layout.row(align=True)
  292. tool_settings = context.scene.tool_settings
  293. settings = tool_settings.gpencil_paint
  294. row.template_ID_preview(settings, "brush", rows=3, cols=8, hide_buttons=True)
  295. if context.object and brush.gpencil_tool in {'FILL', 'DRAW'}:
  296. draw_color_selector()
  297. from bl_ui.properties_paint_common import (
  298. brush_basic_gpencil_paint_settings,
  299. )
  300. brush_basic_gpencil_paint_settings(layout, context, brush, compact=True)
  301. # FIXME: tools must use their own UI drawing!
  302. if tool.idname in {"builtin.arc", "builtin.curve", "builtin.line", "builtin.box", "builtin.circle"}:
  303. settings = context.tool_settings.gpencil_sculpt
  304. row = layout.row(align=True)
  305. row.prop(settings, "use_thickness_curve", text="", icon='CURVE_DATA')
  306. sub = row.row(align=True)
  307. sub.active = settings.use_thickness_curve
  308. sub.popover(
  309. panel="TOPBAR_PT_gpencil_primitive",
  310. text="Thickness Profile",
  311. )
  312. if brush.gpencil_tool == 'FILL':
  313. settings = context.tool_settings.gpencil_sculpt
  314. row = layout.row(align=True)
  315. sub = row.row(align=True)
  316. sub.popover(
  317. panel="TOPBAR_PT_gpencil_fill",
  318. text="Fill Options",
  319. )
  320. @staticmethod
  321. def SCULPT_GPENCIL(context, layout, tool):
  322. if (tool is None) or (not tool.has_datablock):
  323. return
  324. tool_settings = context.tool_settings
  325. settings = tool_settings.gpencil_sculpt
  326. brush = settings.brush
  327. from bl_ui.properties_paint_common import (
  328. brush_basic_gpencil_sculpt_settings,
  329. )
  330. brush_basic_gpencil_sculpt_settings(layout, context, brush, compact=True)
  331. @staticmethod
  332. def WEIGHT_GPENCIL(context, layout, tool):
  333. if (tool is None) or (not tool.has_datablock):
  334. return
  335. tool_settings = context.tool_settings
  336. settings = tool_settings.gpencil_sculpt
  337. brush = settings.brush
  338. from bl_ui.properties_paint_common import (
  339. brush_basic_gpencil_weight_settings,
  340. )
  341. brush_basic_gpencil_weight_settings(layout, context, brush, compact=True)
  342. @staticmethod
  343. def PARTICLE(context, layout, tool):
  344. if (tool is None) or (not tool.has_datablock):
  345. return
  346. # See: 'VIEW3D_PT_tools_brush', basically a duplicate
  347. settings = context.tool_settings.particle_edit
  348. brush = settings.brush
  349. tool = settings.tool
  350. if tool != 'NONE':
  351. layout.prop(brush, "size", slider=True)
  352. if tool == 'ADD':
  353. layout.prop(brush, "count")
  354. layout.prop(settings, "use_default_interpolate")
  355. layout.prop(brush, "steps", slider=True)
  356. layout.prop(settings, "default_key_count", slider=True)
  357. else:
  358. layout.prop(brush, "strength", slider=True)
  359. if tool == 'LENGTH':
  360. layout.row().prop(brush, "length_mode", expand=True)
  361. elif tool == 'PUFF':
  362. layout.row().prop(brush, "puff_mode", expand=True)
  363. layout.prop(brush, "use_puff_volume")
  364. elif tool == 'COMB':
  365. row = layout.row()
  366. row.active = settings.is_editable
  367. row.prop(settings, "use_emitter_deflect", text="Deflect Emitter")
  368. sub = row.row(align=True)
  369. sub.active = settings.use_emitter_deflect
  370. sub.prop(settings, "emitter_distance", text="Distance")
  371. class VIEW3D_HT_header(Header):
  372. bl_space_type = 'VIEW_3D'
  373. @staticmethod
  374. def draw_xform_template(layout, context):
  375. obj = context.active_object
  376. object_mode = 'OBJECT' if obj is None else obj.mode
  377. has_pose_mode = (
  378. (object_mode == 'POSE') or
  379. (object_mode == 'WEIGHT_PAINT' and context.pose_object is not None)
  380. )
  381. tool_settings = context.tool_settings
  382. # Mode & Transform Settings
  383. scene = context.scene
  384. # Orientation
  385. if object_mode in {'OBJECT', 'EDIT', 'EDIT_GPENCIL'} or has_pose_mode:
  386. orient_slot = scene.transform_orientation_slots[0]
  387. row = layout.row(align=True)
  388. sub = row.row()
  389. sub.ui_units_x = 4
  390. sub.prop_with_popover(
  391. orient_slot,
  392. "type",
  393. text="",
  394. panel="VIEW3D_PT_transform_orientations",
  395. )
  396. # Pivot
  397. if object_mode in {'OBJECT', 'EDIT', 'EDIT_GPENCIL', 'SCULPT_GPENCIL'} or has_pose_mode:
  398. layout.prop_with_popover(
  399. tool_settings,
  400. "transform_pivot_point",
  401. text="",
  402. icon_only=True,
  403. panel="VIEW3D_PT_pivot_point",
  404. )
  405. # Snap
  406. show_snap = False
  407. if obj is None:
  408. show_snap = True
  409. else:
  410. if (object_mode not in {
  411. 'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT',
  412. 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'
  413. }) or has_pose_mode:
  414. show_snap = True
  415. else:
  416. from bl_ui.properties_paint_common import UnifiedPaintPanel
  417. paint_settings = UnifiedPaintPanel.paint_settings(context)
  418. if paint_settings:
  419. brush = paint_settings.brush
  420. if brush and brush.stroke_method == 'CURVE':
  421. show_snap = True
  422. if show_snap:
  423. snap_items = bpy.types.ToolSettings.bl_rna.properties["snap_elements"].enum_items
  424. snap_elements = tool_settings.snap_elements
  425. if len(snap_elements) == 1:
  426. text = ""
  427. for elem in snap_elements:
  428. icon = snap_items[elem].icon
  429. break
  430. else:
  431. text = "Mix"
  432. icon = 'NONE'
  433. del snap_items, snap_elements
  434. row = layout.row(align=True)
  435. row.prop(tool_settings, "use_snap", text="")
  436. sub = row.row(align=True)
  437. sub.popover(
  438. panel="VIEW3D_PT_snapping",
  439. icon=icon,
  440. text=text,
  441. )
  442. # Proportional editing
  443. if object_mode in {'EDIT', 'PARTICLE_EDIT', 'SCULPT_GPENCIL', 'EDIT_GPENCIL', 'OBJECT'}:
  444. row = layout.row(align=True)
  445. kw = {}
  446. if object_mode == 'OBJECT':
  447. attr = "use_proportional_edit_objects"
  448. else:
  449. attr = "use_proportional_edit"
  450. if tool_settings.use_proportional_edit:
  451. if tool_settings.use_proportional_connected:
  452. kw["icon"] = 'PROP_CON'
  453. elif tool_settings.use_proportional_projected:
  454. kw["icon"] = 'PROP_PROJECTED'
  455. else:
  456. kw["icon"] = 'PROP_ON'
  457. else:
  458. kw["icon"] = 'PROP_OFF'
  459. row.prop(tool_settings, attr, icon_only=True, **kw)
  460. sub = row.row(align=True)
  461. sub.active = getattr(tool_settings, attr)
  462. sub.prop_with_popover(
  463. tool_settings,
  464. "proportional_edit_falloff",
  465. text="",
  466. icon_only=True,
  467. panel="VIEW3D_PT_proportional_edit",
  468. )
  469. def draw(self, context):
  470. layout = self.layout
  471. tool_settings = context.tool_settings
  472. view = context.space_data
  473. shading = view.shading
  474. # mode_string = context.mode
  475. obj = context.active_object
  476. show_region_tool_header = view.show_region_tool_header
  477. if not show_region_tool_header:
  478. layout.row(align=True).template_header()
  479. row = layout.row(align=True)
  480. object_mode = 'OBJECT' if obj is None else obj.mode
  481. # Note: This is actually deadly in case enum_items have to be dynamically generated
  482. # (because internal RNA array iterator will free everything immediately...).
  483. # XXX This is an RNA internal issue, not sure how to fix it.
  484. # Note: Tried to add an accessor to get translated UI strings instead of manual call
  485. # to pgettext_iface below, but this fails because translated enumitems
  486. # are always dynamically allocated.
  487. act_mode_item = bpy.types.Object.bl_rna.properties["mode"].enum_items[object_mode]
  488. act_mode_i18n_context = bpy.types.Object.bl_rna.properties["mode"].translation_context
  489. sub = row.row(align=True)
  490. sub.ui_units_x = 5.5
  491. sub.operator_menu_enum(
  492. "object.mode_set", "mode",
  493. text=bpy.app.translations.pgettext_iface(act_mode_item.name, act_mode_i18n_context),
  494. icon=act_mode_item.icon,
  495. )
  496. del act_mode_item
  497. layout.template_header_3D_mode()
  498. # Contains buttons like Mode, Pivot, Layer, Mesh Select Mode...
  499. if obj:
  500. # Particle edit
  501. if object_mode == 'PARTICLE_EDIT':
  502. row = layout.row()
  503. row.prop(tool_settings.particle_edit, "select_mode", text="", expand=True)
  504. # Grease Pencil
  505. if obj and obj.type == 'GPENCIL' and context.gpencil_data:
  506. gpd = context.gpencil_data
  507. if gpd.is_stroke_paint_mode:
  508. row = layout.row()
  509. sub = row.row(align=True)
  510. sub.prop(tool_settings, "use_gpencil_draw_onback", text="", icon='MOD_OPACITY')
  511. sub.separator(factor=0.4)
  512. sub.prop(tool_settings, "use_gpencil_weight_data_add", text="", icon='WPAINT_HLT')
  513. sub.separator(factor=0.4)
  514. sub.prop(tool_settings, "use_gpencil_draw_additive", text="", icon='FREEZE')
  515. if gpd.use_stroke_edit_mode:
  516. row = layout.row(align=True)
  517. row.prop(tool_settings, "gpencil_selectmode", text="", expand=True)
  518. if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode:
  519. row = layout.row(align=True)
  520. if gpd.is_stroke_sculpt_mode:
  521. row.prop(tool_settings.gpencil_sculpt, "use_select_mask", text="")
  522. row.separator()
  523. row.prop(gpd, "use_multiedit", text="", icon='GP_MULTIFRAME_EDITING')
  524. sub = row.row(align=True)
  525. sub.active = gpd.use_multiedit
  526. sub.popover(
  527. panel="VIEW3D_PT_gpencil_multi_frame",
  528. text="Multiframe",
  529. )
  530. if gpd.use_stroke_edit_mode:
  531. row = layout.row(align=True)
  532. row.prop(tool_settings.gpencil_sculpt, "use_select_mask", text="")
  533. row.popover(
  534. panel="VIEW3D_PT_tools_grease_pencil_interpolate",
  535. text="Interpolate",
  536. )
  537. overlay = view.overlay
  538. VIEW3D_MT_editor_menus.draw_collapsible(context, layout)
  539. layout.separator_spacer()
  540. if object_mode in {'PAINT_GPENCIL', 'SCULPT_GPENCIL'}:
  541. # Grease pencil
  542. if object_mode == 'PAINT_GPENCIL':
  543. layout.prop_with_popover(
  544. tool_settings,
  545. "gpencil_stroke_placement_view3d",
  546. text="",
  547. panel="VIEW3D_PT_gpencil_origin",
  548. )
  549. if object_mode in {'PAINT_GPENCIL', 'SCULPT_GPENCIL'}:
  550. layout.prop_with_popover(
  551. tool_settings.gpencil_sculpt,
  552. "lock_axis",
  553. text="",
  554. panel="VIEW3D_PT_gpencil_lock",
  555. )
  556. if object_mode == 'PAINT_GPENCIL':
  557. # FIXME: this is bad practice!
  558. # Tool options are to be displayed in the topbar.
  559. if context.workspace.tools.from_space_view3d_mode(object_mode).idname == "builtin_brush.Draw":
  560. settings = tool_settings.gpencil_sculpt.guide
  561. row = layout.row(align=True)
  562. row.prop(settings, "use_guide", text="", icon='GRID')
  563. sub = row.row(align=True)
  564. sub.active = settings.use_guide
  565. sub.popover(
  566. panel="VIEW3D_PT_gpencil_guide",
  567. text="Guides",
  568. )
  569. layout.separator_spacer()
  570. elif not show_region_tool_header:
  571. # Transform settings depending on tool header visibility
  572. VIEW3D_HT_header.draw_xform_template(layout, context)
  573. layout.separator_spacer()
  574. # Viewport Settings
  575. layout.popover(
  576. panel="VIEW3D_PT_object_type_visibility",
  577. icon_value=view.icon_from_show_object_viewport,
  578. text="",
  579. )
  580. # Gizmo toggle & popover.
  581. row = layout.row(align=True)
  582. # FIXME: place-holder icon.
  583. row.prop(view, "show_gizmo", text="", toggle=True, icon='GIZMO')
  584. sub = row.row(align=True)
  585. sub.active = view.show_gizmo
  586. sub.popover(
  587. panel="VIEW3D_PT_gizmo_display",
  588. text="",
  589. )
  590. # Overlay toggle & popover.
  591. row = layout.row(align=True)
  592. row.prop(overlay, "show_overlays", icon='OVERLAY', text="")
  593. sub = row.row(align=True)
  594. sub.active = overlay.show_overlays
  595. sub.popover(panel="VIEW3D_PT_overlay", text="")
  596. row = layout.row()
  597. row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
  598. if shading.type == 'WIREFRAME':
  599. row.prop(shading, "show_xray_wireframe", text="", icon='XRAY')
  600. else:
  601. row.prop(shading, "show_xray", text="", icon='XRAY')
  602. row = layout.row(align=True)
  603. row.prop(shading, "type", text="", expand=True)
  604. sub = row.row(align=True)
  605. # TODO, currently render shading type ignores mesh two-side, until it's supported
  606. # show the shading popover which shows double-sided option.
  607. # sub.enabled = shading.type != 'RENDERED'
  608. sub.popover(panel="VIEW3D_PT_shading", text="")
  609. class VIEW3D_MT_editor_menus(Menu):
  610. bl_label = ""
  611. def draw(self, context):
  612. layout = self.layout
  613. obj = context.active_object
  614. mode_string = context.mode
  615. edit_object = context.edit_object
  616. gp_edit = obj and obj.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}
  617. layout.menu("VIEW3D_MT_view")
  618. # Select Menu
  619. if gp_edit:
  620. if mode_string not in {'PAINT_GPENCIL', 'WEIGHT_GPENCIL'}:
  621. layout.menu("VIEW3D_MT_select_gpencil")
  622. elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
  623. mesh = obj.data
  624. if mesh.use_paint_mask:
  625. layout.menu("VIEW3D_MT_select_paint_mask")
  626. elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
  627. layout.menu("VIEW3D_MT_select_paint_mask_vertex")
  628. elif mode_string != 'SCULPT':
  629. layout.menu("VIEW3D_MT_select_%s" % mode_string.lower())
  630. if gp_edit:
  631. pass
  632. elif mode_string == 'OBJECT':
  633. layout.menu("VIEW3D_MT_add", text="Add", text_ctxt=i18n_contexts.operator_default)
  634. elif mode_string == 'EDIT_MESH':
  635. layout.menu("VIEW3D_MT_mesh_add", text="Add", text_ctxt=i18n_contexts.operator_default)
  636. elif mode_string == 'EDIT_CURVE':
  637. layout.menu("VIEW3D_MT_curve_add", text="Add", text_ctxt=i18n_contexts.operator_default)
  638. elif mode_string == 'EDIT_SURFACE':
  639. layout.menu("VIEW3D_MT_surface_add", text="Add", text_ctxt=i18n_contexts.operator_default)
  640. elif mode_string == 'EDIT_METABALL':
  641. layout.menu("VIEW3D_MT_metaball_add", text="Add", text_ctxt=i18n_contexts.operator_default)
  642. elif mode_string == 'EDIT_ARMATURE':
  643. layout.menu("TOPBAR_MT_edit_armature_add", text="Add", text_ctxt=i18n_contexts.operator_default)
  644. if gp_edit:
  645. if obj and obj.mode == 'PAINT_GPENCIL':
  646. layout.menu("VIEW3D_MT_paint_gpencil")
  647. elif obj and obj.mode == 'EDIT_GPENCIL':
  648. layout.menu("VIEW3D_MT_edit_gpencil")
  649. elif obj and obj.mode == 'WEIGHT_GPENCIL':
  650. layout.menu("VIEW3D_MT_weight_gpencil")
  651. elif edit_object:
  652. layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower())
  653. if mode_string == 'EDIT_MESH':
  654. layout.menu("VIEW3D_MT_edit_mesh_vertices")
  655. layout.menu("VIEW3D_MT_edit_mesh_edges")
  656. layout.menu("VIEW3D_MT_edit_mesh_faces")
  657. layout.menu("VIEW3D_MT_uv_map", text="UV")
  658. elif mode_string in {'EDIT_CURVE', 'EDIT_SURFACE'}:
  659. layout.menu("VIEW3D_MT_edit_curve_ctrlpoints")
  660. layout.menu("VIEW3D_MT_edit_curve_segments")
  661. elif obj:
  662. if mode_string != 'PAINT_TEXTURE':
  663. layout.menu("VIEW3D_MT_%s" % mode_string.lower())
  664. if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE'}:
  665. layout.menu("VIEW3D_MT_brush")
  666. if mode_string == 'SCULPT':
  667. layout.menu("VIEW3D_MT_hide_mask")
  668. else:
  669. layout.menu("VIEW3D_MT_object")
  670. # ********** Menu **********
  671. # ********** Utilities **********
  672. class ShowHideMenu:
  673. bl_label = "Show/Hide"
  674. _operator_name = ""
  675. def draw(self, _context):
  676. layout = self.layout
  677. layout.operator("%s.reveal" % self._operator_name)
  678. layout.operator("%s.hide" % self._operator_name, text="Hide Selected").unselected = False
  679. layout.operator("%s.hide" % self._operator_name, text="Hide Unselected").unselected = True
  680. # Standard transforms which apply to all cases
  681. # NOTE: this doesn't seem to be able to be used directly
  682. class VIEW3D_MT_transform_base(Menu):
  683. bl_label = "Transform"
  684. bl_category = "View"
  685. # TODO: get rid of the custom text strings?
  686. def draw(self, context):
  687. layout = self.layout
  688. layout.operator("transform.translate")
  689. layout.operator("transform.rotate")
  690. layout.operator("transform.resize", text="Scale")
  691. layout.separator()
  692. layout.operator("transform.tosphere", text="To Sphere")
  693. layout.operator("transform.shear", text="Shear")
  694. layout.operator("transform.bend", text="Bend")
  695. layout.operator("transform.push_pull", text="Push/Pull")
  696. if context.mode != 'OBJECT':
  697. layout.operator("transform.vertex_warp", text="Warp")
  698. layout.operator("transform.vertex_random", text="Randomize")
  699. # Generic transform menu - geometry types
  700. class VIEW3D_MT_transform(VIEW3D_MT_transform_base):
  701. def draw(self, context):
  702. # base menu
  703. VIEW3D_MT_transform_base.draw(self, context)
  704. # generic...
  705. layout = self.layout
  706. if context.mode == 'EDIT_MESH':
  707. layout.operator("transform.shrink_fatten", text="Shrink Fatten")
  708. elif context.mode == 'EDIT_CURVE':
  709. layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
  710. layout.separator()
  711. layout.operator("transform.translate", text="Move Texture Space").texture_space = True
  712. layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
  713. # Object-specific extensions to Transform menu
  714. class VIEW3D_MT_transform_object(VIEW3D_MT_transform_base):
  715. def draw(self, context):
  716. layout = self.layout
  717. # base menu
  718. VIEW3D_MT_transform_base.draw(self, context)
  719. # object-specific option follow...
  720. layout.separator()
  721. layout.operator("transform.translate", text="Move Texture Space").texture_space = True
  722. layout.operator("transform.resize", text="Scale Texture Space").texture_space = True
  723. layout.separator()
  724. layout.operator_context = 'EXEC_REGION_WIN'
  725. # XXX see alignmenu() in edit.c of b2.4x to get this working
  726. layout.operator("transform.transform", text="Align to Transform Orientation").mode = 'ALIGN'
  727. layout.separator()
  728. layout.operator("object.randomize_transform")
  729. layout.operator("object.align")
  730. # TODO: there is a strange context bug here.
  731. """
  732. layout.operator_context = 'INVOKE_REGION_WIN'
  733. layout.operator("object.transform_axis_target")
  734. """
  735. # Armature EditMode extensions to Transform menu
  736. class VIEW3D_MT_transform_armature(VIEW3D_MT_transform_base):
  737. def draw(self, context):
  738. layout = self.layout
  739. # base menu
  740. VIEW3D_MT_transform_base.draw(self, context)
  741. # armature specific extensions follow...
  742. obj = context.object
  743. if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'}:
  744. if obj.data.display_type == 'BBONE':
  745. layout.separator()
  746. layout.operator("transform.transform", text="Scale BBone").mode = 'BONE_SIZE'
  747. elif obj.data.display_type == 'ENVELOPE':
  748. layout.separator()
  749. layout.operator("transform.transform", text="Scale Envelope Distance").mode = 'BONE_SIZE'
  750. layout.operator("transform.transform", text="Scale Radius").mode = 'BONE_ENVELOPE'
  751. if context.edit_object and context.edit_object.type == 'ARMATURE':
  752. layout.separator()
  753. layout.operator("armature.align")
  754. class VIEW3D_MT_mirror(Menu):
  755. bl_label = "Mirror"
  756. def draw(self, _context):
  757. layout = self.layout
  758. layout.operator("transform.mirror", text="Interactive Mirror")
  759. layout.separator()
  760. layout.operator_context = 'EXEC_REGION_WIN'
  761. for (space_name, space_id) in (("Global", 'GLOBAL'), ("Local", 'LOCAL')):
  762. for axis_index, axis_name in enumerate("XYZ"):
  763. props = layout.operator("transform.mirror", text=f"{axis_name!s} {space_name!s}")
  764. props.constraint_axis[axis_index] = True
  765. props.orient_type = 'GLOBAL'
  766. if space_id == 'GLOBAL':
  767. layout.separator()
  768. class VIEW3D_MT_snap(Menu):
  769. bl_label = "Snap"
  770. def draw(self, _context):
  771. layout = self.layout
  772. layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid")
  773. layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False
  774. layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Keep Offset)").use_offset = True
  775. layout.operator("view3d.snap_selected_to_active", text="Selection to Active")
  776. layout.separator()
  777. layout.operator("view3d.snap_cursor_to_selected", text="Cursor to Selected")
  778. layout.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin")
  779. layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
  780. layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
  781. class VIEW3D_MT_uv_map(Menu):
  782. bl_label = "UV Mapping"
  783. def draw(self, context):
  784. layout = self.layout
  785. tool_settings = context.tool_settings
  786. layout.operator("uv.unwrap")
  787. layout.prop(tool_settings, "use_edge_path_live_unwrap")
  788. layout.separator()
  789. layout.operator_context = 'INVOKE_DEFAULT'
  790. layout.operator("uv.smart_project")
  791. layout.operator("uv.lightmap_pack")
  792. layout.operator("uv.follow_active_quads")
  793. layout.separator()
  794. layout.operator_context = 'EXEC_REGION_WIN'
  795. layout.operator("uv.cube_project")
  796. layout.operator("uv.cylinder_project")
  797. layout.operator("uv.sphere_project")
  798. layout.separator()
  799. layout.operator_context = 'INVOKE_REGION_WIN'
  800. layout.operator("uv.project_from_view").scale_to_bounds = False
  801. layout.operator("uv.project_from_view", text="Project from View (Bounds)").scale_to_bounds = True
  802. layout.separator()
  803. layout.operator("mesh.mark_seam").clear = False
  804. layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
  805. layout.separator()
  806. layout.operator("uv.reset")
  807. # ********** View menus **********
  808. class VIEW3D_MT_view(Menu):
  809. bl_label = "View"
  810. def draw(self, context):
  811. layout = self.layout
  812. view = context.space_data
  813. layout.prop(view, "show_region_toolbar")
  814. layout.prop(view, "show_region_ui")
  815. layout.prop(view, "show_region_tool_header")
  816. layout.prop(view, "show_region_hud")
  817. layout.separator()
  818. layout.operator("view3d.view_selected", text="Frame Selected").use_all_regions = False
  819. if view.region_quadviews:
  820. layout.operator("view3d.view_selected", text="Frame Selected (Quad View)").use_all_regions = True
  821. layout.operator("view3d.view_all", text="Frame All").center = False
  822. layout.operator("view3d.view_persportho", text="Perspective/Orthographic")
  823. layout.menu("VIEW3D_MT_view_local")
  824. layout.separator()
  825. layout.menu("VIEW3D_MT_view_cameras", text="Cameras")
  826. layout.separator()
  827. layout.menu("VIEW3D_MT_view_viewpoint")
  828. layout.menu("VIEW3D_MT_view_navigation")
  829. layout.menu("VIEW3D_MT_view_align")
  830. layout.separator()
  831. layout.operator_context = 'INVOKE_REGION_WIN'
  832. layout.menu("VIEW3D_MT_view_regions", text="View Regions")
  833. layout.separator()
  834. layout.operator("screen.animation_play", text="Play Animation")
  835. layout.separator()
  836. layout.operator("render.opengl", text="Viewport Render Image", icon='RENDER_STILL')
  837. layout.operator("render.opengl", text="Viewport Render Animation", icon='RENDER_ANIMATION').animation = True
  838. layout.separator()
  839. layout.menu("INFO_MT_area")
  840. class VIEW3D_MT_view_local(Menu):
  841. bl_label = "Local View"
  842. def draw(self, _context):
  843. layout = self.layout
  844. layout.operator("view3d.localview", text="Toggle Local View")
  845. layout.operator("view3d.localview_remove_from")
  846. class VIEW3D_MT_view_cameras(Menu):
  847. bl_label = "Cameras"
  848. def draw(self, _context):
  849. layout = self.layout
  850. layout.operator("view3d.object_as_camera")
  851. layout.operator("view3d.view_camera", text="Active Camera")
  852. class VIEW3D_MT_view_viewpoint(Menu):
  853. bl_label = "Viewpoint"
  854. def draw(self, _context):
  855. layout = self.layout
  856. layout.operator("view3d.view_camera", text="Camera")
  857. layout.separator()
  858. layout.operator("view3d.view_axis", text="Top").type = 'TOP'
  859. layout.operator("view3d.view_axis", text="Bottom").type = 'BOTTOM'
  860. layout.separator()
  861. layout.operator("view3d.view_axis", text="Front").type = 'FRONT'
  862. layout.operator("view3d.view_axis", text="Back").type = 'BACK'
  863. layout.separator()
  864. layout.operator("view3d.view_axis", text="Right").type = 'RIGHT'
  865. layout.operator("view3d.view_axis", text="Left").type = 'LEFT'
  866. class VIEW3D_MT_view_navigation(Menu):
  867. bl_label = "Navigation"
  868. def draw(self, _context):
  869. from math import pi
  870. layout = self.layout
  871. layout.operator_enum("view3d.view_orbit", "type")
  872. props = layout.operator("view3d.view_orbit", text="Orbit Opposite")
  873. props.type = 'ORBITRIGHT'
  874. props.angle = pi
  875. layout.separator()
  876. layout.operator("view3d.view_roll", text="Roll Left").type = 'LEFT'
  877. layout.operator("view3d.view_roll", text="Roll Right").type = 'RIGHT'
  878. layout.separator()
  879. layout.operator_enum("view3d.view_pan", "type")
  880. layout.separator()
  881. layout.operator("view3d.zoom", text="Zoom In").delta = 1
  882. layout.operator("view3d.zoom", text="Zoom Out").delta = -1
  883. layout.operator("view3d.zoom_border", text="Zoom Region...")
  884. layout.operator("view3d.zoom_camera_1_to_1", text="Zoom Camera 1:1")
  885. layout.separator()
  886. layout.operator("view3d.fly")
  887. layout.operator("view3d.walk")
  888. class VIEW3D_MT_view_align(Menu):
  889. bl_label = "Align View"
  890. def draw(self, _context):
  891. layout = self.layout
  892. layout.menu("VIEW3D_MT_view_align_selected")
  893. layout.separator()
  894. layout.operator("view3d.camera_to_view", text="Align Active Camera to View")
  895. layout.operator("view3d.camera_to_view_selected", text="Align Active Camera to Selected")
  896. layout.separator()
  897. layout.operator("view3d.view_all", text="Center Cursor and View All").center = True
  898. layout.operator("view3d.view_center_cursor")
  899. layout.separator()
  900. layout.operator("view3d.view_lock_to_active")
  901. layout.operator("view3d.view_lock_clear")
  902. class VIEW3D_MT_view_align_selected(Menu):
  903. bl_label = "Align View to Active"
  904. def draw(self, _context):
  905. layout = self.layout
  906. props = layout.operator("view3d.view_axis", text="Top")
  907. props.align_active = True
  908. props.type = 'TOP'
  909. props = layout.operator("view3d.view_axis", text="Bottom")
  910. props.align_active = True
  911. props.type = 'BOTTOM'
  912. layout.separator()
  913. props = layout.operator("view3d.view_axis", text="Front")
  914. props.align_active = True
  915. props.type = 'FRONT'
  916. props = layout.operator("view3d.view_axis", text="Back")
  917. props.align_active = True
  918. props.type = 'BACK'
  919. layout.separator()
  920. props = layout.operator("view3d.view_axis", text="Right")
  921. props.align_active = True
  922. props.type = 'RIGHT'
  923. props = layout.operator("view3d.view_axis", text="Left")
  924. props.align_active = True
  925. props.type = 'LEFT'
  926. class VIEW3D_MT_view_regions(Menu):
  927. bl_label = "View Regions"
  928. def draw(self, _context):
  929. layout = self.layout
  930. layout.operator("view3d.clip_border", text="Clipping Region...")
  931. layout.operator("view3d.render_border", text="Render Region...")
  932. layout.separator()
  933. layout.operator("view3d.clear_render_border")
  934. # ********** Select menus, suffix from context.mode **********
  935. class VIEW3D_MT_select_object_more_less(Menu):
  936. bl_label = "Select More/Less"
  937. def draw(self, _context):
  938. layout = self.layout
  939. layout = self.layout
  940. layout.operator("object.select_more", text="More")
  941. layout.operator("object.select_less", text="Less")
  942. layout.separator()
  943. props = layout.operator("object.select_hierarchy", text="Parent")
  944. props.extend = False
  945. props.direction = 'PARENT'
  946. props = layout.operator("object.select_hierarchy", text="Child")
  947. props.extend = False
  948. props.direction = 'CHILD'
  949. layout.separator()
  950. props = layout.operator("object.select_hierarchy", text="Extend Parent")
  951. props.extend = True
  952. props.direction = 'PARENT'
  953. props = layout.operator("object.select_hierarchy", text="Extend Child")
  954. props.extend = True
  955. props.direction = 'CHILD'
  956. class VIEW3D_MT_select_object(Menu):
  957. bl_label = "Select"
  958. def draw(self, _context):
  959. layout = self.layout
  960. layout.operator("object.select_all", text="All").action = 'SELECT'
  961. layout.operator("object.select_all", text="None").action = 'DESELECT'
  962. layout.operator("object.select_all", text="Invert").action = 'INVERT'
  963. layout.separator()
  964. layout.operator("view3d.select_box")
  965. layout.operator("view3d.select_circle")
  966. layout.separator()
  967. layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...")
  968. layout.operator("object.select_camera", text="Select Active Camera")
  969. layout.operator("object.select_mirror", text="Mirror Selection")
  970. layout.operator("object.select_random", text="Select Random")
  971. layout.separator()
  972. layout.menu("VIEW3D_MT_select_object_more_less")
  973. layout.separator()
  974. layout.operator_menu_enum("object.select_grouped", "type", text="Select Grouped")
  975. layout.operator_menu_enum("object.select_linked", "type", text="Select Linked")
  976. layout.operator("object.select_pattern", text="Select Pattern...")
  977. class VIEW3D_MT_select_pose_more_less(Menu):
  978. bl_label = "Select More/Less"
  979. def draw(self, _context):
  980. layout = self.layout
  981. layout = self.layout
  982. props = layout.operator("pose.select_hierarchy", text="Parent")
  983. props.extend = False
  984. props.direction = 'PARENT'
  985. props = layout.operator("pose.select_hierarchy", text="Child")
  986. props.extend = False
  987. props.direction = 'CHILD'
  988. layout.separator()
  989. props = layout.operator("pose.select_hierarchy", text="Extend Parent")
  990. props.extend = True
  991. props.direction = 'PARENT'
  992. props = layout.operator("pose.select_hierarchy", text="Extend Child")
  993. props.extend = True
  994. props.direction = 'CHILD'
  995. class VIEW3D_MT_select_pose(Menu):
  996. bl_label = "Select"
  997. def draw(self, _context):
  998. layout = self.layout
  999. layout.operator("pose.select_all", text="All").action = 'SELECT'
  1000. layout.operator("pose.select_all", text="None").action = 'DESELECT'
  1001. layout.operator("pose.select_all", text="Invert").action = 'INVERT'
  1002. layout.separator()
  1003. layout.operator("view3d.select_box")
  1004. layout.operator("view3d.select_circle")
  1005. layout.separator()
  1006. layout.operator("pose.select_mirror", text="Flip Active")
  1007. layout.separator()
  1008. layout.operator("pose.select_constraint_target", text="Constraint Target")
  1009. layout.operator("pose.select_linked", text="Linked")
  1010. layout.separator()
  1011. layout.menu("VIEW3D_MT_select_pose_more_less")
  1012. layout.separator()
  1013. layout.operator_menu_enum("pose.select_grouped", "type", text="Grouped")
  1014. layout.operator("object.select_pattern", text="Select Pattern...")
  1015. class VIEW3D_MT_select_particle(Menu):
  1016. bl_label = "Select"
  1017. def draw(self, _context):
  1018. layout = self.layout
  1019. layout.operator("particle.select_all", text="All").action = 'SELECT'
  1020. layout.operator("particle.select_all", text="None").action = 'DESELECT'
  1021. layout.operator("particle.select_all", text="Invert").action = 'INVERT'
  1022. layout.separator()
  1023. layout.operator("view3d.select_box")
  1024. layout.operator("view3d.select_circle")
  1025. layout.separator()
  1026. layout.operator("particle.select_linked")
  1027. layout.separator()
  1028. layout.operator("particle.select_more")
  1029. layout.operator("particle.select_less")
  1030. layout.separator()
  1031. layout.operator("particle.select_random")
  1032. layout.separator()
  1033. layout.operator("particle.select_roots", text="Roots")
  1034. layout.operator("particle.select_tips", text="Tips")
  1035. class VIEW3D_MT_edit_mesh_select_similar(Menu):
  1036. bl_label = "Select Similar"
  1037. def draw(self, _context):
  1038. layout = self.layout
  1039. layout.operator_enum("mesh.select_similar", "type")
  1040. layout.separator()
  1041. layout.operator("mesh.select_similar_region", text="Face Regions")
  1042. class VIEW3D_MT_edit_mesh_select_by_trait(Menu):
  1043. bl_label = "Select All by Trait"
  1044. def draw(self, context):
  1045. layout = self.layout
  1046. tool_settings = context.tool_settings
  1047. if tool_settings.mesh_select_mode[2] is False:
  1048. layout.operator("mesh.select_non_manifold", text="Non Manifold")
  1049. layout.operator("mesh.select_loose", text="Loose Geometry")
  1050. layout.operator("mesh.select_interior_faces", text="Interior Faces")
  1051. layout.operator("mesh.select_face_by_sides", text="Faces by Sides")
  1052. layout.separator()
  1053. layout.operator("mesh.select_ungrouped", text="Ungrouped Verts")
  1054. class VIEW3D_MT_edit_mesh_select_more_less(Menu):
  1055. bl_label = "Select More/Less"
  1056. def draw(self, _context):
  1057. layout = self.layout
  1058. layout.operator("mesh.select_more", text="More")
  1059. layout.operator("mesh.select_less", text="Less")
  1060. layout.separator()
  1061. layout.operator("mesh.select_next_item", text="Next Active")
  1062. layout.operator("mesh.select_prev_item", text="Previous Active")
  1063. class VIEW3D_MT_edit_mesh_select_linked(Menu):
  1064. bl_label = "Select Linked"
  1065. def draw(self, _context):
  1066. layout = self.layout
  1067. layout.operator("mesh.select_linked", text="Linked")
  1068. layout.operator("mesh.shortest_path_select", text="Shortest Path")
  1069. layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces")
  1070. class VIEW3D_MT_edit_mesh_select_loops(Menu):
  1071. bl_label = "Select Loops"
  1072. def draw(self, _context):
  1073. layout = self.layout
  1074. layout.operator("mesh.loop_multi_select", text="Edge Loops").ring = False
  1075. layout.operator("mesh.loop_multi_select", text="Edge Rings").ring = True
  1076. layout.separator()
  1077. layout.operator("mesh.loop_to_region")
  1078. layout.operator("mesh.region_to_loop")
  1079. class VIEW3D_MT_select_edit_mesh(Menu):
  1080. bl_label = "Select"
  1081. def draw(self, _context):
  1082. layout = self.layout
  1083. # primitive
  1084. layout.operator("mesh.select_all", text="All").action = 'SELECT'
  1085. layout.operator("mesh.select_all", text="None").action = 'DESELECT'
  1086. layout.operator("mesh.select_all", text="Invert").action = 'INVERT'
  1087. layout.separator()
  1088. layout.operator("view3d.select_box")
  1089. layout.operator("view3d.select_circle")
  1090. layout.separator()
  1091. # numeric
  1092. layout.operator("mesh.select_random", text="Select Random")
  1093. layout.operator("mesh.select_nth")
  1094. layout.separator()
  1095. # geometric
  1096. layout.operator("mesh.edges_select_sharp", text="Select Sharp Edges")
  1097. layout.separator()
  1098. # other ...
  1099. layout.menu("VIEW3D_MT_edit_mesh_select_similar")
  1100. layout.separator()
  1101. layout.menu("VIEW3D_MT_edit_mesh_select_by_trait")
  1102. layout.separator()
  1103. layout.menu("VIEW3D_MT_edit_mesh_select_more_less")
  1104. layout.separator()
  1105. layout.menu("VIEW3D_MT_edit_mesh_select_loops")
  1106. layout.separator()
  1107. layout.menu("VIEW3D_MT_edit_mesh_select_linked")
  1108. layout.separator()
  1109. layout.operator("mesh.select_axis", text="Side of Active")
  1110. layout.operator("mesh.select_mirror", text="Mirror Selection")
  1111. class VIEW3D_MT_select_edit_curve(Menu):
  1112. bl_label = "Select"
  1113. def draw(self, _context):
  1114. layout = self.layout
  1115. layout.operator("curve.select_all", text="All").action = 'SELECT'
  1116. layout.operator("curve.select_all", text="None").action = 'DESELECT'
  1117. layout.operator("curve.select_all", text="Invert").action = 'INVERT'
  1118. layout.separator()
  1119. layout.operator("view3d.select_box")
  1120. layout.operator("view3d.select_circle")
  1121. layout.separator()
  1122. layout.operator("curve.select_random")
  1123. layout.operator("curve.select_nth")
  1124. layout.operator("curve.select_linked", text="Select Linked")
  1125. layout.operator("curve.select_similar", text="Select Similar")
  1126. layout.separator()
  1127. layout.operator("curve.de_select_first")
  1128. layout.operator("curve.de_select_last")
  1129. layout.operator("curve.select_next")
  1130. layout.operator("curve.select_previous")
  1131. layout.separator()
  1132. layout.operator("curve.select_more")
  1133. layout.operator("curve.select_less")
  1134. class VIEW3D_MT_select_edit_surface(Menu):
  1135. bl_label = "Select"
  1136. def draw(self, _context):
  1137. layout = self.layout
  1138. layout.operator("curve.select_all", text="All").action = 'SELECT'
  1139. layout.operator("curve.select_all", text="None").action = 'DESELECT'
  1140. layout.operator("curve.select_all", text="Invert").action = 'INVERT'
  1141. layout.separator()
  1142. layout.operator("view3d.select_box")
  1143. layout.operator("view3d.select_circle")
  1144. layout.separator()
  1145. layout.operator("curve.select_random")
  1146. layout.operator("curve.select_nth")
  1147. layout.operator("curve.select_linked", text="Select Linked")
  1148. layout.operator("curve.select_similar", text="Select Similar")
  1149. layout.separator()
  1150. layout.operator("curve.select_row")
  1151. layout.separator()
  1152. layout.operator("curve.select_more")
  1153. layout.operator("curve.select_less")
  1154. class VIEW3D_MT_edit_text_context_menu(Menu):
  1155. bl_label = "Text Context Menu"
  1156. def draw(self, _context):
  1157. layout = self.layout
  1158. layout.operator_context = 'INVOKE_DEFAULT'
  1159. layout.operator("font.text_cut", text="Cut")
  1160. layout.operator("font.text_copy", text="Copy", icon='COPYDOWN')
  1161. layout.operator("font.text_paste", text="Paste", icon='PASTEDOWN')
  1162. layout.separator()
  1163. layout.operator("font.select_all")
  1164. layout.separator()
  1165. layout.menu("VIEW3D_MT_edit_font")
  1166. class VIEW3D_MT_select_edit_text(Menu):
  1167. # intentional name mismatch
  1168. # select menu for 3d-text doesn't make sense
  1169. bl_label = "Edit"
  1170. def draw(self, _context):
  1171. layout = self.layout
  1172. layout.operator("ed.undo")
  1173. layout.operator("ed.redo")
  1174. layout.separator()
  1175. layout.operator("font.text_cut", text="Cut")
  1176. layout.operator("font.text_copy", text="Copy", icon='COPYDOWN')
  1177. layout.operator("font.text_paste", text="Paste", icon='PASTEDOWN')
  1178. layout.separator()
  1179. layout.operator("font.text_paste_from_file")
  1180. layout.separator()
  1181. layout.operator("font.select_all")
  1182. layout.separator()
  1183. layout.operator("font.case_set", text="To Uppercase").case = 'UPPER'
  1184. layout.operator("font.case_set", text="To Lowercase").case = 'LOWER'
  1185. layout.separator()
  1186. layout.menu("VIEW3D_MT_edit_text_chars")
  1187. class VIEW3D_MT_select_edit_metaball(Menu):
  1188. bl_label = "Select"
  1189. def draw(self, _context):
  1190. layout = self.layout
  1191. layout.operator("mball.select_all", text="All").action = 'SELECT'
  1192. layout.operator("mball.select_all", text="None").action = 'DESELECT'
  1193. layout.operator("mball.select_all", text="Invert").action = 'INVERT'
  1194. layout.separator()
  1195. layout.operator("view3d.select_box")
  1196. layout.operator("view3d.select_circle")
  1197. layout.separator()
  1198. layout.operator("mball.select_random_metaelems")
  1199. layout.separator()
  1200. layout.operator_menu_enum("mball.select_similar", "type", text="Similar")
  1201. class VIEW3D_MT_edit_lattice_context_menu(Menu):
  1202. bl_label = "Lattice Context Menu"
  1203. def draw(self, _context):
  1204. layout = self.layout
  1205. layout = self.layout
  1206. layout.menu("VIEW3D_MT_mirror")
  1207. layout.operator_menu_enum("lattice.flip", "axis")
  1208. layout.menu("VIEW3D_MT_snap")
  1209. layout.separator()
  1210. layout.operator("lattice.make_regular")
  1211. class VIEW3D_MT_select_edit_lattice(Menu):
  1212. bl_label = "Select"
  1213. def draw(self, _context):
  1214. layout = self.layout
  1215. layout.operator("lattice.select_all", text="All").action = 'SELECT'
  1216. layout.operator("lattice.select_all", text="None").action = 'DESELECT'
  1217. layout.operator("lattice.select_all", text="Invert").action = 'INVERT'
  1218. layout.separator()
  1219. layout.operator("view3d.select_box")
  1220. layout.operator("view3d.select_circle")
  1221. layout.separator()
  1222. layout.operator("lattice.select_mirror")
  1223. layout.operator("lattice.select_random")
  1224. layout.separator()
  1225. layout.operator("lattice.select_more")
  1226. layout.operator("lattice.select_less")
  1227. layout.separator()
  1228. layout.operator("lattice.select_ungrouped", text="Ungrouped Verts")
  1229. class VIEW3D_MT_select_edit_armature(Menu):
  1230. bl_label = "Select"
  1231. def draw(self, _context):
  1232. layout = self.layout
  1233. layout.operator("armature.select_all", text="All").action = 'SELECT'
  1234. layout.operator("armature.select_all", text="None").action = 'DESELECT'
  1235. layout.operator("armature.select_all", text="Invert").action = 'INVERT'
  1236. layout.separator()
  1237. layout.operator("view3d.select_box")
  1238. layout.operator("view3d.select_circle")
  1239. layout.separator()
  1240. layout.operator("armature.select_mirror", text="Mirror").extend = False
  1241. layout.separator()
  1242. layout.operator("armature.select_more", text="More")
  1243. layout.operator("armature.select_less", text="Less")
  1244. layout.separator()
  1245. props = layout.operator("armature.select_hierarchy", text="Parent")
  1246. props.extend = False
  1247. props.direction = 'PARENT'
  1248. props = layout.operator("armature.select_hierarchy", text="Child")
  1249. props.extend = False
  1250. props.direction = 'CHILD'
  1251. layout.separator()
  1252. props = layout.operator("armature.select_hierarchy", text="Extend Parent")
  1253. props.extend = True
  1254. props.direction = 'PARENT'
  1255. props = layout.operator("armature.select_hierarchy", text="Extend Child")
  1256. props.extend = True
  1257. props.direction = 'CHILD'
  1258. layout.operator_menu_enum("armature.select_similar", "type", text="Similar")
  1259. layout.operator("object.select_pattern", text="Select Pattern...")
  1260. class VIEW3D_MT_select_gpencil(Menu):
  1261. bl_label = "Select"
  1262. def draw(self, _context):
  1263. layout = self.layout
  1264. layout.operator("gpencil.select_all", text="All").action = 'SELECT'
  1265. layout.operator("gpencil.select_all", text="None").action = 'DESELECT'
  1266. layout.operator("gpencil.select_all", text="Invert").action = 'INVERT'
  1267. layout.separator()
  1268. layout.operator("gpencil.select_box")
  1269. layout.operator("gpencil.select_circle")
  1270. layout.separator()
  1271. layout.operator("gpencil.select_linked", text="Linked")
  1272. layout.operator("gpencil.select_alternate")
  1273. layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped")
  1274. layout.separator()
  1275. layout.operator("gpencil.select_first")
  1276. layout.operator("gpencil.select_last")
  1277. layout.separator()
  1278. layout.operator("gpencil.select_more")
  1279. layout.operator("gpencil.select_less")
  1280. class VIEW3D_MT_select_paint_mask(Menu):
  1281. bl_label = "Select"
  1282. def draw(self, _context):
  1283. layout = self.layout
  1284. layout.operator("paint.face_select_all", text="All").action = 'SELECT'
  1285. layout.operator("paint.face_select_all", text="None").action = 'DESELECT'
  1286. layout.operator("paint.face_select_all", text="Invert").action = 'INVERT'
  1287. layout.separator()
  1288. layout.operator("view3d.select_box")
  1289. layout.operator("view3d.select_circle")
  1290. layout.separator()
  1291. layout.operator("paint.face_select_linked", text="Linked")
  1292. class VIEW3D_MT_select_paint_mask_vertex(Menu):
  1293. bl_label = "Select"
  1294. def draw(self, _context):
  1295. layout = self.layout
  1296. layout.operator("paint.vert_select_all", text="All").action = 'SELECT'
  1297. layout.operator("paint.vert_select_all", text="None").action = 'DESELECT'
  1298. layout.operator("paint.vert_select_all", text="Invert").action = 'INVERT'
  1299. layout.separator()
  1300. layout.operator("view3d.select_box")
  1301. layout.operator("view3d.select_circle")
  1302. layout.separator()
  1303. layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts")
  1304. class VIEW3D_MT_angle_control(Menu):
  1305. bl_label = "Angle Control"
  1306. @classmethod
  1307. def poll(cls, context):
  1308. settings = UnifiedPaintPanel.paint_settings(context)
  1309. if not settings:
  1310. return False
  1311. brush = settings.brush
  1312. tex_slot = brush.texture_slot
  1313. return tex_slot.has_texture_angle and tex_slot.has_texture_angle_source
  1314. def draw(self, context):
  1315. layout = self.layout
  1316. settings = UnifiedPaintPanel.paint_settings(context)
  1317. brush = settings.brush
  1318. sculpt = (context.sculpt_object is not None)
  1319. tex_slot = brush.texture_slot
  1320. layout.prop(tex_slot, "use_rake", text="Rake")
  1321. if brush.brush_capabilities.has_random_texture_angle and tex_slot.has_random_texture_angle:
  1322. if sculpt:
  1323. if brush.sculpt_capabilities.has_random_texture_angle:
  1324. layout.prop(tex_slot, "use_random", text="Random")
  1325. else:
  1326. layout.prop(tex_slot, "use_random", text="Random")
  1327. class VIEW3D_MT_mesh_add(Menu):
  1328. bl_idname = "VIEW3D_MT_mesh_add"
  1329. bl_label = "Mesh"
  1330. def draw(self, _context):
  1331. layout = self.layout
  1332. layout.operator_context = 'INVOKE_REGION_WIN'
  1333. layout.operator("mesh.primitive_plane_add", text="Plane", icon='MESH_PLANE')
  1334. layout.operator("mesh.primitive_cube_add", text="Cube", icon='MESH_CUBE')
  1335. layout.operator("mesh.primitive_circle_add", text="Circle", icon='MESH_CIRCLE')
  1336. layout.operator("mesh.primitive_uv_sphere_add", text="UV Sphere", icon='MESH_UVSPHERE')
  1337. layout.operator("mesh.primitive_ico_sphere_add", text="Ico Sphere", icon='MESH_ICOSPHERE')
  1338. layout.operator("mesh.primitive_cylinder_add", text="Cylinder", icon='MESH_CYLINDER')
  1339. layout.operator("mesh.primitive_cone_add", text="Cone", icon='MESH_CONE')
  1340. layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS')
  1341. layout.separator()
  1342. layout.operator("mesh.primitive_grid_add", text="Grid", icon='MESH_GRID')
  1343. layout.operator("mesh.primitive_monkey_add", text="Monkey", icon='MESH_MONKEY')
  1344. class VIEW3D_MT_curve_add(Menu):
  1345. bl_idname = "VIEW3D_MT_curve_add"
  1346. bl_label = "Curve"
  1347. def draw(self, _context):
  1348. layout = self.layout
  1349. layout.operator_context = 'INVOKE_REGION_WIN'
  1350. layout.operator("curve.primitive_bezier_curve_add", text="Bezier", icon='CURVE_BEZCURVE')
  1351. layout.operator("curve.primitive_bezier_circle_add", text="Circle", icon='CURVE_BEZCIRCLE')
  1352. layout.separator()
  1353. layout.operator("curve.primitive_nurbs_curve_add", text="Nurbs Curve", icon='CURVE_NCURVE')
  1354. layout.operator("curve.primitive_nurbs_circle_add", text="Nurbs Circle", icon='CURVE_NCIRCLE')
  1355. layout.operator("curve.primitive_nurbs_path_add", text="Path", icon='CURVE_PATH')
  1356. class VIEW3D_MT_surface_add(Menu):
  1357. bl_idname = "VIEW3D_MT_surface_add"
  1358. bl_label = "Surface"
  1359. def draw(self, _context):
  1360. layout = self.layout
  1361. layout.operator_context = 'INVOKE_REGION_WIN'
  1362. layout.operator("surface.primitive_nurbs_surface_curve_add", text="Nurbs Curve", icon='SURFACE_NCURVE')
  1363. layout.operator("surface.primitive_nurbs_surface_circle_add", text="Nurbs Circle", icon='SURFACE_NCIRCLE')
  1364. layout.operator("surface.primitive_nurbs_surface_surface_add", text="Nurbs Surface", icon='SURFACE_NSURFACE')
  1365. layout.operator("surface.primitive_nurbs_surface_cylinder_add",
  1366. text="Nurbs Cylinder", icon='SURFACE_NCYLINDER')
  1367. layout.operator("surface.primitive_nurbs_surface_sphere_add", text="Nurbs Sphere", icon='SURFACE_NSPHERE')
  1368. layout.operator("surface.primitive_nurbs_surface_torus_add", text="Nurbs Torus", icon='SURFACE_NTORUS')
  1369. class VIEW3D_MT_edit_metaball_context_menu(Menu):
  1370. bl_label = "Metaball Context Menu"
  1371. def draw(self, _context):
  1372. layout = self.layout
  1373. layout.operator_context = 'INVOKE_REGION_WIN'
  1374. # Add
  1375. layout.operator("mball.duplicate_move")
  1376. layout.separator()
  1377. # Modify
  1378. layout.menu("VIEW3D_MT_mirror")
  1379. layout.menu("VIEW3D_MT_snap")
  1380. layout.separator()
  1381. # Remove
  1382. layout.operator_context = 'EXEC_DEFAULT'
  1383. layout.operator("mball.delete_metaelems", text="Delete")
  1384. class VIEW3D_MT_metaball_add(Menu):
  1385. bl_idname = "VIEW3D_MT_metaball_add"
  1386. bl_label = "Metaball"
  1387. def draw(self, _context):
  1388. layout = self.layout
  1389. layout.operator_context = 'INVOKE_REGION_WIN'
  1390. layout.operator_enum("object.metaball_add", "type")
  1391. class TOPBAR_MT_edit_curve_add(Menu):
  1392. bl_idname = "TOPBAR_MT_edit_curve_add"
  1393. bl_label = "Add"
  1394. bl_translation_context = i18n_contexts.operator_default
  1395. def draw(self, context):
  1396. is_surf = context.active_object.type == 'SURFACE'
  1397. layout = self.layout
  1398. layout.operator_context = 'EXEC_REGION_WIN'
  1399. if is_surf:
  1400. VIEW3D_MT_surface_add.draw(self, context)
  1401. else:
  1402. VIEW3D_MT_curve_add.draw(self, context)
  1403. class TOPBAR_MT_edit_armature_add(Menu):
  1404. bl_idname = "TOPBAR_MT_edit_armature_add"
  1405. bl_label = "Armature"
  1406. def draw(self, _context):
  1407. layout = self.layout
  1408. layout.operator_context = 'EXEC_REGION_WIN'
  1409. layout.operator("armature.bone_primitive_add", text="Single Bone", icon='BONE_DATA')
  1410. class VIEW3D_MT_armature_add(Menu):
  1411. bl_idname = "VIEW3D_MT_armature_add"
  1412. bl_label = "Armature"
  1413. def draw(self, _context):
  1414. layout = self.layout
  1415. layout.operator_context = 'EXEC_REGION_WIN'
  1416. layout.operator("object.armature_add", text="Single Bone", icon='BONE_DATA')
  1417. class VIEW3D_MT_light_add(Menu):
  1418. bl_idname = "VIEW3D_MT_light_add"
  1419. bl_label = "Light"
  1420. def draw(self, _context):
  1421. layout = self.layout
  1422. layout.operator_context = 'INVOKE_REGION_WIN'
  1423. layout.operator_enum("object.light_add", "type")
  1424. class VIEW3D_MT_lightprobe_add(Menu):
  1425. bl_idname = "VIEW3D_MT_lightprobe_add"
  1426. bl_label = "Light Probe"
  1427. def draw(self, _context):
  1428. layout = self.layout
  1429. layout.operator_context = 'INVOKE_REGION_WIN'
  1430. layout.operator_enum("object.lightprobe_add", "type")
  1431. class VIEW3D_MT_camera_add(Menu):
  1432. bl_idname = "VIEW3D_MT_camera_add"
  1433. bl_label = "Camera"
  1434. def draw(self, _context):
  1435. layout = self.layout
  1436. layout.operator_context = 'EXEC_REGION_WIN'
  1437. layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA')
  1438. class VIEW3D_MT_add(Menu):
  1439. bl_label = "Add"
  1440. bl_translation_context = i18n_contexts.operator_default
  1441. def draw(self, context):
  1442. layout = self.layout
  1443. # note, don't use 'EXEC_SCREEN' or operators won't get the 'v3d' context.
  1444. # Note: was EXEC_AREA, but this context does not have the 'rv3d', which prevents
  1445. # "align_view" to work on first call (see [#32719]).
  1446. layout.operator_context = 'EXEC_REGION_WIN'
  1447. # layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
  1448. layout.menu("VIEW3D_MT_mesh_add", icon='OUTLINER_OB_MESH')
  1449. # layout.operator_menu_enum("object.curve_add", "type", text="Curve", icon='OUTLINER_OB_CURVE')
  1450. layout.menu("VIEW3D_MT_curve_add", icon='OUTLINER_OB_CURVE')
  1451. # layout.operator_menu_enum("object.surface_add", "type", text="Surface", icon='OUTLINER_OB_SURFACE')
  1452. layout.menu("VIEW3D_MT_surface_add", icon='OUTLINER_OB_SURFACE')
  1453. layout.menu("VIEW3D_MT_metaball_add", text="Metaball", icon='OUTLINER_OB_META')
  1454. layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
  1455. layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL')
  1456. layout.separator()
  1457. if VIEW3D_MT_armature_add.is_extended():
  1458. layout.menu("VIEW3D_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
  1459. else:
  1460. layout.operator("object.armature_add", text="Armature", icon='OUTLINER_OB_ARMATURE')
  1461. layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
  1462. layout.separator()
  1463. layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY')
  1464. layout.menu("VIEW3D_MT_image_add", text="Image", icon='OUTLINER_OB_IMAGE')
  1465. layout.separator()
  1466. layout.menu("VIEW3D_MT_light_add", icon='OUTLINER_OB_LIGHT')
  1467. layout.menu("VIEW3D_MT_lightprobe_add", icon='OUTLINER_OB_LIGHTPROBE')
  1468. layout.separator()
  1469. if VIEW3D_MT_camera_add.is_extended():
  1470. layout.menu("VIEW3D_MT_camera_add", icon='OUTLINER_OB_CAMERA')
  1471. else:
  1472. VIEW3D_MT_camera_add.draw(self, context)
  1473. layout.separator()
  1474. layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
  1475. layout.separator()
  1476. layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_FORCE_FIELD')
  1477. layout.separator()
  1478. has_collections = bool(bpy.data.collections)
  1479. col = layout.column()
  1480. col.enabled = has_collections
  1481. if not has_collections or len(bpy.data.collections) > 10:
  1482. col.operator_context = 'INVOKE_REGION_WIN'
  1483. col.operator(
  1484. "object.collection_instance_add",
  1485. text="Collection Instance..." if has_collections else "No Collections to Instance",
  1486. icon='OUTLINER_OB_GROUP_INSTANCE',
  1487. )
  1488. else:
  1489. col.operator_menu_enum(
  1490. "object.collection_instance_add",
  1491. "collection",
  1492. text="Collection Instance",
  1493. icon='OUTLINER_OB_GROUP_INSTANCE',
  1494. )
  1495. class VIEW3D_MT_image_add(Menu):
  1496. bl_label = "Add Image"
  1497. def draw(self, _context):
  1498. layout = self.layout
  1499. layout.operator("object.load_reference_image", text="Reference", icon='IMAGE_REFERENCE')
  1500. layout.operator("object.load_background_image", text="Background", icon='IMAGE_BACKGROUND')
  1501. class VIEW3D_MT_object_relations(Menu):
  1502. bl_label = "Relations"
  1503. def draw(self, _context):
  1504. layout = self.layout
  1505. layout.operator("object.proxy_make", text="Make Proxy...")
  1506. layout.operator("object.make_dupli_face")
  1507. layout.separator()
  1508. layout.operator_menu_enum("object.make_local", "type", text="Make Local...")
  1509. layout.menu("VIEW3D_MT_make_single_user")
  1510. layout.separator()
  1511. layout.operator("object.data_transfer")
  1512. layout.operator("object.datalayout_transfer")
  1513. class VIEW3D_MT_object(Menu):
  1514. bl_context = "objectmode"
  1515. bl_label = "Object"
  1516. def draw(self, context):
  1517. layout = self.layout
  1518. layout.menu("VIEW3D_MT_transform_object")
  1519. layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
  1520. layout.menu("VIEW3D_MT_mirror")
  1521. layout.menu("VIEW3D_MT_object_clear")
  1522. layout.menu("VIEW3D_MT_object_apply")
  1523. layout.menu("VIEW3D_MT_snap")
  1524. layout.separator()
  1525. layout.operator("object.duplicate_move")
  1526. layout.operator("object.duplicate_move_linked")
  1527. layout.operator("object.join")
  1528. layout.separator()
  1529. layout.operator("view3d.copybuffer", text="Copy Objects", icon='COPYDOWN')
  1530. layout.operator("view3d.pastebuffer", text="Paste Objects", icon='PASTEDOWN')
  1531. layout.separator()
  1532. layout.menu("VIEW3D_MT_object_parent")
  1533. layout.menu("VIEW3D_MT_object_collection")
  1534. layout.menu("VIEW3D_MT_object_relations")
  1535. layout.menu("VIEW3D_MT_object_constraints")
  1536. layout.menu("VIEW3D_MT_object_track")
  1537. layout.menu("VIEW3D_MT_make_links", text="Make Links")
  1538. layout.separator()
  1539. layout.operator("object.shade_smooth")
  1540. layout.operator("object.shade_flat")
  1541. layout.separator()
  1542. layout.menu("VIEW3D_MT_object_animation")
  1543. layout.menu("VIEW3D_MT_object_rigid_body")
  1544. layout.separator()
  1545. layout.menu("VIEW3D_MT_object_quick_effects")
  1546. layout.separator()
  1547. ob = context.active_object
  1548. if ob and ob.type == 'GPENCIL' and context.gpencil_data:
  1549. layout.operator_menu_enum("gpencil.convert", "type", text="Convert to")
  1550. else:
  1551. layout.operator_menu_enum("object.convert", "target")
  1552. layout.separator()
  1553. layout.menu("VIEW3D_MT_object_showhide")
  1554. layout.separator()
  1555. layout.operator_context = 'EXEC_DEFAULT'
  1556. layout.operator("object.delete", text="Delete").use_global = False
  1557. layout.operator("object.delete", text="Delete Global").use_global = True
  1558. class VIEW3D_MT_object_animation(Menu):
  1559. bl_label = "Animation"
  1560. def draw(self, _context):
  1561. layout = self.layout
  1562. layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...")
  1563. layout.operator("anim.keyframe_delete_v3d", text="Delete Keyframes...")
  1564. layout.operator("anim.keyframe_clear_v3d", text="Clear Keyframes...")
  1565. layout.operator("anim.keying_set_active_set", text="Change Keying Set...")
  1566. layout.separator()
  1567. layout.operator("nla.bake", text="Bake Action...")
  1568. class VIEW3D_MT_object_rigid_body(Menu):
  1569. bl_label = "Rigid Body"
  1570. def draw(self, _context):
  1571. layout = self.layout
  1572. layout.operator("rigidbody.objects_add", text="Add Active").type = 'ACTIVE'
  1573. layout.operator("rigidbody.objects_add", text="Add Passive").type = 'PASSIVE'
  1574. layout.separator()
  1575. layout.operator("rigidbody.objects_remove", text="Remove")
  1576. layout.separator()
  1577. layout.operator("rigidbody.shape_change", text="Change Shape")
  1578. layout.operator("rigidbody.mass_calculate", text="Calculate Mass")
  1579. layout.operator("rigidbody.object_settings_copy", text="Copy from Active")
  1580. layout.operator("object.visual_transform_apply", text="Apply Transformation")
  1581. layout.operator("rigidbody.bake_to_keyframes", text="Bake To Keyframes")
  1582. layout.separator()
  1583. layout.operator("rigidbody.connect", text="Connect")
  1584. class VIEW3D_MT_object_clear(Menu):
  1585. bl_label = "Clear"
  1586. def draw(self, _context):
  1587. layout = self.layout
  1588. layout.operator("object.location_clear", text="Location").clear_delta = False
  1589. layout.operator("object.rotation_clear", text="Rotation").clear_delta = False
  1590. layout.operator("object.scale_clear", text="Scale").clear_delta = False
  1591. layout.separator()
  1592. layout.operator("object.origin_clear", text="Origin")
  1593. class VIEW3D_MT_object_context_menu(Menu):
  1594. bl_label = "Object Context Menu"
  1595. def draw(self, context):
  1596. layout = self.layout
  1597. view = context.space_data
  1598. obj = context.object
  1599. selected_objects_len = len(context.selected_objects)
  1600. # If nothing is selected
  1601. # (disabled for now until it can be made more useful).
  1602. '''
  1603. if selected_objects_len == 0:
  1604. layout.menu("VIEW3D_MT_add", text="Add", text_ctxt=i18n_contexts.operator_default)
  1605. layout.operator("view3d.pastebuffer", text="Paste Objects", icon='PASTEDOWN')
  1606. return
  1607. '''
  1608. # If something is selected
  1609. if obj is not None and obj.type in {'MESH', 'CURVE', 'SURFACE'}:
  1610. layout.operator("object.shade_smooth", text="Shade Smooth")
  1611. layout.operator("object.shade_flat", text="Shade Flat")
  1612. layout.separator()
  1613. if obj is None:
  1614. pass
  1615. elif obj.type == 'MESH':
  1616. layout.operator_context = 'INVOKE_REGION_WIN'
  1617. layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
  1618. layout.operator_context = 'INVOKE_DEFAULT'
  1619. # If more than one object is selected
  1620. if selected_objects_len > 1:
  1621. layout.operator("object.join")
  1622. layout.separator()
  1623. elif obj.type == 'CAMERA':
  1624. layout.operator_context = 'INVOKE_REGION_WIN'
  1625. if obj.data.type == 'PERSP':
  1626. props = layout.operator("wm.context_modal_mouse", text="Camera Lens Angle")
  1627. props.data_path_iter = "selected_editable_objects"
  1628. props.data_path_item = "data.lens"
  1629. props.input_scale = 0.1
  1630. if obj.data.lens_unit == 'MILLIMETERS':
  1631. props.header_text = "Camera Lens Angle: %.1fmm"
  1632. else:
  1633. props.header_text = "Camera Lens Angle: %.1f\u00B0"
  1634. else:
  1635. props = layout.operator("wm.context_modal_mouse", text="Camera Lens Scale")
  1636. props.data_path_iter = "selected_editable_objects"
  1637. props.data_path_item = "data.ortho_scale"
  1638. props.input_scale = 0.01
  1639. props.header_text = "Camera Lens Scale: %.3f"
  1640. if not obj.data.dof.focus_object:
  1641. if view and view.camera == obj and view.region_3d.view_perspective == 'CAMERA':
  1642. props = layout.operator("ui.eyedropper_depth", text="DOF Distance (Pick)")
  1643. else:
  1644. props = layout.operator("wm.context_modal_mouse", text="DOF Distance")
  1645. props.data_path_iter = "selected_editable_objects"
  1646. props.data_path_item = "data.dof.focus_distance"
  1647. props.input_scale = 0.02
  1648. props.header_text = "DOF Distance: %.3f"
  1649. layout.separator()
  1650. elif obj.type in {'CURVE', 'FONT'}:
  1651. layout.operator_context = 'INVOKE_REGION_WIN'
  1652. props = layout.operator("wm.context_modal_mouse", text="Extrude Size")
  1653. props.data_path_iter = "selected_editable_objects"
  1654. props.data_path_item = "data.extrude"
  1655. props.input_scale = 0.01
  1656. props.header_text = "Extrude Size: %.3f"
  1657. props = layout.operator("wm.context_modal_mouse", text="Width Size")
  1658. props.data_path_iter = "selected_editable_objects"
  1659. props.data_path_item = "data.offset"
  1660. props.input_scale = 0.01
  1661. props.header_text = "Width Size: %.3f"
  1662. layout.separator()
  1663. layout.operator("object.convert", text="Convert to Mesh").target = 'MESH'
  1664. layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
  1665. layout.separator()
  1666. elif obj.type == 'GPENCIL':
  1667. layout.operator("gpencil.convert", text="Convert to Path").type = 'PATH'
  1668. layout.operator("gpencil.convert", text="Convert to Bezier Curves").type = 'CURVE'
  1669. layout.operator("gpencil.convert", text="Convert to Mesh").type = 'POLY'
  1670. layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
  1671. layout.separator()
  1672. elif obj.type == 'EMPTY':
  1673. layout.operator_context = 'INVOKE_REGION_WIN'
  1674. props = layout.operator("wm.context_modal_mouse", text="Empty Draw Size")
  1675. props.data_path_iter = "selected_editable_objects"
  1676. props.data_path_item = "empty_display_size"
  1677. props.input_scale = 0.01
  1678. props.header_text = "Empty Draw Size: %.3f"
  1679. layout.separator()
  1680. elif obj.type == 'LIGHT':
  1681. light = obj.data
  1682. layout.operator_context = 'INVOKE_REGION_WIN'
  1683. props = layout.operator("wm.context_modal_mouse", text="Energy")
  1684. props.data_path_iter = "selected_editable_objects"
  1685. props.data_path_item = "data.energy"
  1686. props.header_text = "Light Energy: %.3f"
  1687. if light.type == 'AREA':
  1688. props = layout.operator("wm.context_modal_mouse", text="Size X")
  1689. props.data_path_iter = "selected_editable_objects"
  1690. props.data_path_item = "data.size"
  1691. props.header_text = "Light Size X: %.3f"
  1692. if light.shape in {'RECTANGLE', 'ELLIPSE'}:
  1693. props = layout.operator("wm.context_modal_mouse", text="Size Y")
  1694. props.data_path_iter = "selected_editable_objects"
  1695. props.data_path_item = "data.size_y"
  1696. props.header_text = "Light Size Y: %.3f"
  1697. elif light.type in {'SPOT', 'POINT'}:
  1698. props = layout.operator("wm.context_modal_mouse", text="Radius")
  1699. props.data_path_iter = "selected_editable_objects"
  1700. props.data_path_item = "data.shadow_soft_size"
  1701. props.header_text = "Light Radius: %.3f"
  1702. elif light.type == 'SUN':
  1703. props = layout.operator("wm.context_modal_mouse", text="Angle")
  1704. props.data_path_iter = "selected_editable_objects"
  1705. props.data_path_item = "data.angle"
  1706. props.header_text = "Light Angle: %.3f"
  1707. if light.type == 'SPOT':
  1708. layout.separator()
  1709. props = layout.operator("wm.context_modal_mouse", text="Spot Size")
  1710. props.data_path_iter = "selected_editable_objects"
  1711. props.data_path_item = "data.spot_size"
  1712. props.input_scale = 0.01
  1713. props.header_text = "Spot Size: %.2f"
  1714. props = layout.operator("wm.context_modal_mouse", text="Spot Blend")
  1715. props.data_path_iter = "selected_editable_objects"
  1716. props.data_path_item = "data.spot_blend"
  1717. props.input_scale = -0.01
  1718. props.header_text = "Spot Blend: %.2f"
  1719. layout.separator()
  1720. layout.operator("view3d.copybuffer", text="Copy Objects", icon='COPYDOWN')
  1721. layout.operator("view3d.pastebuffer", text="Paste Objects", icon='PASTEDOWN')
  1722. layout.separator()
  1723. layout.operator("object.duplicate_move", icon='DUPLICATE')
  1724. layout.operator("object.duplicate_move_linked")
  1725. layout.separator()
  1726. props = layout.operator("wm.call_panel", text="Rename Active Object...")
  1727. props.name = "TOPBAR_PT_name"
  1728. props.keep_open = False
  1729. layout.separator()
  1730. layout.menu("VIEW3D_MT_mirror")
  1731. layout.menu("VIEW3D_MT_snap")
  1732. layout.menu("VIEW3D_MT_object_parent")
  1733. layout.operator_context = 'INVOKE_REGION_WIN'
  1734. if view and view.local_view:
  1735. layout.operator("view3d.localview_remove_from")
  1736. else:
  1737. layout.operator("object.move_to_collection")
  1738. layout.separator()
  1739. layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...")
  1740. layout.separator()
  1741. layout.operator_context = 'EXEC_DEFAULT'
  1742. layout.operator("object.delete", text="Delete").use_global = False
  1743. class VIEW3D_MT_object_shading(Menu):
  1744. # XXX, this menu is a place to store shading operator in object mode
  1745. bl_label = "Shading"
  1746. def draw(self, _context):
  1747. layout = self.layout
  1748. layout.operator("object.shade_smooth", text="Smooth")
  1749. layout.operator("object.shade_flat", text="Flat")
  1750. class VIEW3D_MT_object_apply(Menu):
  1751. bl_label = "Apply"
  1752. def draw(self, _context):
  1753. layout = self.layout
  1754. props = layout.operator("object.transform_apply", text="Location", text_ctxt=i18n_contexts.default)
  1755. props.location, props.rotation, props.scale = True, False, False
  1756. props = layout.operator("object.transform_apply", text="Rotation", text_ctxt=i18n_contexts.default)
  1757. props.location, props.rotation, props.scale = False, True, False
  1758. props = layout.operator("object.transform_apply", text="Scale", text_ctxt=i18n_contexts.default)
  1759. props.location, props.rotation, props.scale = False, False, True
  1760. props = layout.operator("object.transform_apply", text="All Transforms", text_ctxt=i18n_contexts.default)
  1761. props.location, props.rotation, props.scale = True, True, True
  1762. props = layout.operator("object.transform_apply", text="Rotation & Scale", text_ctxt=i18n_contexts.default)
  1763. props.location, props.rotation, props.scale = False, True, True
  1764. layout.separator()
  1765. layout.operator(
  1766. "object.transforms_to_deltas",
  1767. text="Location to Deltas",
  1768. text_ctxt=i18n_contexts.default,
  1769. ).mode = 'LOC'
  1770. layout.operator(
  1771. "object.transforms_to_deltas",
  1772. text="Rotation to Deltas",
  1773. text_ctxt=i18n_contexts.default,
  1774. ).mode = 'ROT'
  1775. layout.operator(
  1776. "object.transforms_to_deltas",
  1777. text="Scale to Deltas",
  1778. text_ctxt=i18n_contexts.default,
  1779. ).mode = 'SCALE'
  1780. layout.operator(
  1781. "object.transforms_to_deltas",
  1782. text="All Transforms to Deltas",
  1783. text_ctxt=i18n_contexts.default,
  1784. ).mode = 'ALL'
  1785. layout.operator("object.anim_transforms_to_deltas")
  1786. layout.separator()
  1787. layout.operator(
  1788. "object.visual_transform_apply",
  1789. text="Visual Transform",
  1790. text_ctxt=i18n_contexts.default,
  1791. )
  1792. layout.operator(
  1793. "object.convert",
  1794. text="Visual Geometry to Mesh",
  1795. text_ctxt=i18n_contexts.default,
  1796. ).target = 'MESH'
  1797. layout.operator("object.duplicates_make_real")
  1798. class VIEW3D_MT_object_parent(Menu):
  1799. bl_label = "Parent"
  1800. def draw(self, _context):
  1801. layout = self.layout
  1802. layout.operator_enum("object.parent_set", "type")
  1803. layout.separator()
  1804. layout.operator_enum("object.parent_clear", "type")
  1805. class VIEW3D_MT_object_track(Menu):
  1806. bl_label = "Track"
  1807. def draw(self, _context):
  1808. layout = self.layout
  1809. layout.operator_enum("object.track_set", "type")
  1810. layout.separator()
  1811. layout.operator_enum("object.track_clear", "type")
  1812. class VIEW3D_MT_object_collection(Menu):
  1813. bl_label = "Collection"
  1814. def draw(self, _context):
  1815. layout = self.layout
  1816. layout.operator("object.move_to_collection")
  1817. layout.operator("object.link_to_collection")
  1818. layout.separator()
  1819. layout.operator("collection.create")
  1820. # layout.operator_menu_enum("collection.objects_remove", "collection") # BUGGY
  1821. layout.operator("collection.objects_remove")
  1822. layout.operator("collection.objects_remove_all")
  1823. layout.separator()
  1824. layout.operator("collection.objects_add_active")
  1825. layout.operator("collection.objects_remove_active")
  1826. class VIEW3D_MT_object_constraints(Menu):
  1827. bl_label = "Constraints"
  1828. def draw(self, _context):
  1829. layout = self.layout
  1830. layout.operator("object.constraint_add_with_targets")
  1831. layout.operator("object.constraints_copy")
  1832. layout.separator()
  1833. layout.operator("object.constraints_clear")
  1834. class VIEW3D_MT_object_quick_effects(Menu):
  1835. bl_label = "Quick Effects"
  1836. def draw(self, _context):
  1837. layout = self.layout
  1838. layout.operator("object.quick_fur")
  1839. layout.operator("object.quick_explode")
  1840. layout.operator("object.quick_smoke")
  1841. layout.operator("object.quick_fluid")
  1842. class VIEW3D_MT_object_showhide(Menu):
  1843. bl_label = "Show/Hide"
  1844. def draw(self, _context):
  1845. layout = self.layout
  1846. layout.operator("object.hide_view_clear")
  1847. layout.separator()
  1848. layout.operator("object.hide_view_set", text="Hide Selected").unselected = False
  1849. layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True
  1850. class VIEW3D_MT_make_single_user(Menu):
  1851. bl_label = "Make Single User"
  1852. def draw(self, _context):
  1853. layout = self.layout
  1854. props = layout.operator("object.make_single_user", text="Object")
  1855. props.object = True
  1856. props.obdata = props.material = props.animation = False
  1857. props = layout.operator("object.make_single_user", text="Object & Data")
  1858. props.object = props.obdata = True
  1859. props.material = props.animation = False
  1860. props = layout.operator("object.make_single_user", text="Object & Data & Materials")
  1861. props.object = props.obdata = props.material = True
  1862. props.animation = False
  1863. props = layout.operator("object.make_single_user", text="Materials")
  1864. props.material = True
  1865. props.object = props.obdata = props.animation = False
  1866. props = layout.operator("object.make_single_user", text="Object Animation")
  1867. props.animation = True
  1868. props.object = props.obdata = props.material = False
  1869. class VIEW3D_MT_make_links(Menu):
  1870. bl_label = "Make Links"
  1871. def draw(self, _context):
  1872. layout = self.layout
  1873. operator_context_default = layout.operator_context
  1874. if len(bpy.data.scenes) > 10:
  1875. layout.operator_context = 'INVOKE_REGION_WIN'
  1876. layout.operator("object.make_links_scene", text="Objects to Scene...", icon='OUTLINER_OB_EMPTY')
  1877. else:
  1878. layout.operator_context = 'EXEC_REGION_WIN'
  1879. layout.operator_menu_enum("object.make_links_scene", "scene", text="Objects to Scene")
  1880. layout.separator()
  1881. layout.operator_context = operator_context_default
  1882. layout.operator_enum("object.make_links_data", "type") # inline
  1883. layout.operator("object.join_uvs") # stupid place to add this!
  1884. class VIEW3D_MT_brush(Menu):
  1885. bl_label = "Brush"
  1886. def draw(self, context):
  1887. layout = self.layout
  1888. tool_settings = context.tool_settings
  1889. settings = UnifiedPaintPanel.paint_settings(context)
  1890. brush = getattr(settings, "brush", None)
  1891. ups = tool_settings.unified_paint_settings
  1892. layout.prop(ups, "use_unified_size", text="Unified Size")
  1893. layout.prop(ups, "use_unified_strength", text="Unified Strength")
  1894. if context.image_paint_object or context.vertex_paint_object:
  1895. layout.prop(ups, "use_unified_color", text="Unified Color")
  1896. layout.separator()
  1897. # skip if no active brush
  1898. if not brush:
  1899. layout.label(text="No Brushes currently available", icon='INFO')
  1900. return
  1901. # brush paint modes
  1902. layout.menu("VIEW3D_MT_brush_paint_modes")
  1903. # brush tool
  1904. if context.sculpt_object:
  1905. layout.operator("brush.reset")
  1906. layout.prop_menu_enum(brush, "sculpt_tool")
  1907. elif context.image_paint_object:
  1908. layout.prop_menu_enum(brush, "image_tool")
  1909. elif context.vertex_paint_object:
  1910. layout.prop_menu_enum(brush, "vertex_tool")
  1911. elif context.weight_paint_object:
  1912. layout.prop_menu_enum(brush, "weight_tool")
  1913. # TODO: still missing a lot of brush options here
  1914. # sculpt options
  1915. if context.sculpt_object:
  1916. sculpt_tool = brush.sculpt_tool
  1917. layout.separator()
  1918. layout.operator_menu_enum("brush.curve_preset", "shape", text="Curve Preset")
  1919. layout.separator()
  1920. if sculpt_tool != 'GRAB':
  1921. layout.prop_menu_enum(brush, "stroke_method")
  1922. if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
  1923. layout.prop_menu_enum(brush, "direction")
  1924. if sculpt_tool == 'LAYER':
  1925. layout.prop(brush, "use_persistent")
  1926. layout.operator("sculpt.set_persistent_base")
  1927. class VIEW3D_MT_brush_paint_modes(Menu):
  1928. bl_label = "Enabled Modes"
  1929. def draw(self, context):
  1930. layout = self.layout
  1931. settings = UnifiedPaintPanel.paint_settings(context)
  1932. brush = settings.brush
  1933. layout.prop(brush, "use_paint_sculpt", text="Sculpt")
  1934. layout.prop(brush, "use_paint_uv_sculpt", text="UV Sculpt")
  1935. layout.prop(brush, "use_paint_vertex", text="Vertex Paint")
  1936. layout.prop(brush, "use_paint_weight", text="Weight Paint")
  1937. layout.prop(brush, "use_paint_image", text="Texture Paint")
  1938. class VIEW3D_MT_paint_vertex(Menu):
  1939. bl_label = "Paint"
  1940. def draw(self, _context):
  1941. layout = self.layout
  1942. layout.operator("paint.vertex_color_set")
  1943. layout.operator("paint.vertex_color_smooth")
  1944. layout.operator("paint.vertex_color_dirt")
  1945. layout.operator("paint.vertex_color_from_weight")
  1946. layout.separator()
  1947. layout.operator("paint.vertex_color_invert", text="Invert")
  1948. layout.operator("paint.vertex_color_levels", text="Levels")
  1949. layout.operator("paint.vertex_color_hsv", text="Hue Saturation Value")
  1950. layout.operator("paint.vertex_color_brightness_contrast", text="Bright/Contrast")
  1951. class VIEW3D_MT_hook(Menu):
  1952. bl_label = "Hooks"
  1953. def draw(self, context):
  1954. layout = self.layout
  1955. layout.operator_context = 'EXEC_AREA'
  1956. layout.operator("object.hook_add_newob")
  1957. layout.operator("object.hook_add_selob").use_bone = False
  1958. layout.operator("object.hook_add_selob", text="Hook to Selected Object Bone").use_bone = True
  1959. if [mod.type == 'HOOK' for mod in context.active_object.modifiers]:
  1960. layout.separator()
  1961. layout.operator_menu_enum("object.hook_assign", "modifier")
  1962. layout.operator_menu_enum("object.hook_remove", "modifier")
  1963. layout.separator()
  1964. layout.operator_menu_enum("object.hook_select", "modifier")
  1965. layout.operator_menu_enum("object.hook_reset", "modifier")
  1966. layout.operator_menu_enum("object.hook_recenter", "modifier")
  1967. class VIEW3D_MT_vertex_group(Menu):
  1968. bl_label = "Vertex Groups"
  1969. def draw(self, context):
  1970. layout = self.layout
  1971. layout.operator_context = 'EXEC_AREA'
  1972. layout.operator("object.vertex_group_assign_new")
  1973. ob = context.active_object
  1974. if ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex):
  1975. if ob.vertex_groups.active:
  1976. layout.separator()
  1977. layout.operator("object.vertex_group_assign", text="Assign to Active Group")
  1978. layout.operator(
  1979. "object.vertex_group_remove_from",
  1980. text="Remove from Active Group",
  1981. ).use_all_groups = False
  1982. layout.operator("object.vertex_group_remove_from", text="Remove from All").use_all_groups = True
  1983. if ob.vertex_groups.active:
  1984. layout.separator()
  1985. layout.operator_menu_enum("object.vertex_group_set_active", "group", text="Set Active Group")
  1986. layout.operator("object.vertex_group_remove", text="Remove Active Group").all = False
  1987. layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True
  1988. class VIEW3D_MT_paint_weight(Menu):
  1989. bl_label = "Weights"
  1990. @staticmethod
  1991. def draw_generic(layout, is_editmode=False):
  1992. if not is_editmode:
  1993. layout.operator("paint.weight_from_bones", text="Assign Automatic From Bones").type = 'AUTOMATIC'
  1994. layout.operator("paint.weight_from_bones", text="Assign From Bone Envelopes").type = 'ENVELOPES'
  1995. layout.separator()
  1996. layout.operator("object.vertex_group_normalize_all", text="Normalize All")
  1997. layout.operator("object.vertex_group_normalize", text="Normalize")
  1998. layout.separator()
  1999. layout.operator("object.vertex_group_mirror", text="Mirror")
  2000. layout.operator("object.vertex_group_invert", text="Invert")
  2001. layout.operator("object.vertex_group_clean", text="Clean")
  2002. layout.separator()
  2003. layout.operator("object.vertex_group_quantize", text="Quantize")
  2004. layout.operator("object.vertex_group_levels", text="Levels")
  2005. layout.operator("object.vertex_group_smooth", text="Smooth")
  2006. if not is_editmode:
  2007. props = layout.operator("object.data_transfer", text="Transfer Weights")
  2008. props.use_reverse_transfer = True
  2009. props.data_type = 'VGROUP_WEIGHTS'
  2010. layout.operator("object.vertex_group_limit_total", text="Limit Total")
  2011. layout.operator("object.vertex_group_fix", text="Fix Deforms")
  2012. if not is_editmode:
  2013. layout.separator()
  2014. layout.operator("paint.weight_set")
  2015. def draw(self, _context):
  2016. self.draw_generic(self.layout, is_editmode=False)
  2017. class VIEW3D_MT_sculpt(Menu):
  2018. bl_label = "Sculpt"
  2019. def draw(self, context):
  2020. layout = self.layout
  2021. tool_settings = context.tool_settings
  2022. sculpt = tool_settings.sculpt
  2023. layout.operator("sculpt.dynamic_topology_toggle", text="Toggle Dynamic Topology")
  2024. layout.separator()
  2025. layout.prop(sculpt, "use_symmetry_x")
  2026. layout.prop(sculpt, "use_symmetry_y")
  2027. layout.prop(sculpt, "use_symmetry_z")
  2028. layout.separator()
  2029. layout.prop(sculpt, "lock_x")
  2030. layout.prop(sculpt, "lock_y")
  2031. layout.prop(sculpt, "lock_z")
  2032. layout.separator()
  2033. layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
  2034. layout.prop(sculpt, "show_low_resolution")
  2035. layout.prop(sculpt, "show_brush")
  2036. layout.prop(sculpt, "use_deform_only")
  2037. layout.prop(sculpt, "show_diffuse_color")
  2038. layout.prop(sculpt, "show_mask")
  2039. class VIEW3D_MT_hide_mask(Menu):
  2040. bl_label = "Hide/Mask"
  2041. def draw(self, _context):
  2042. layout = self.layout
  2043. props = layout.operator("paint.hide_show", text="Show All")
  2044. props.action = 'SHOW'
  2045. props.area = 'ALL'
  2046. props = layout.operator("paint.hide_show", text="Hide Bounding Box")
  2047. props.action = 'HIDE'
  2048. props.area = 'INSIDE'
  2049. props = layout.operator("paint.hide_show", text="Show Bounding Box")
  2050. props.action = 'SHOW'
  2051. props.area = 'INSIDE'
  2052. props = layout.operator("paint.hide_show", text="Hide Masked")
  2053. props.area = 'MASKED'
  2054. props.action = 'HIDE'
  2055. layout.separator()
  2056. props = layout.operator("paint.mask_flood_fill", text="Invert Mask")
  2057. props.mode = 'INVERT'
  2058. props = layout.operator("paint.mask_flood_fill", text="Fill Mask")
  2059. props.mode = 'VALUE'
  2060. props.value = 1
  2061. props = layout.operator("paint.mask_flood_fill", text="Clear Mask")
  2062. props.mode = 'VALUE'
  2063. props.value = 0
  2064. props = layout.operator("view3d.select_box", text="Box Mask")
  2065. props = layout.operator("paint.mask_lasso_gesture", text="Lasso Mask")
  2066. class VIEW3D_MT_particle(Menu):
  2067. bl_label = "Particle"
  2068. def draw(self, context):
  2069. layout = self.layout
  2070. tool_settings = context.tool_settings
  2071. particle_edit = tool_settings.particle_edit
  2072. layout.operator("particle.mirror")
  2073. layout.operator("particle.remove_doubles")
  2074. layout.separator()
  2075. if particle_edit.select_mode == 'POINT':
  2076. layout.operator("particle.subdivide")
  2077. layout.operator("particle.unify_length")
  2078. layout.operator("particle.rekey")
  2079. layout.operator("particle.weight_set")
  2080. layout.separator()
  2081. layout.menu("VIEW3D_MT_particle_showhide")
  2082. layout.separator()
  2083. layout.operator("particle.delete")
  2084. class VIEW3D_MT_particle_context_menu(Menu):
  2085. bl_label = "Particle Context Menu"
  2086. def draw(self, context):
  2087. layout = self.layout
  2088. tool_settings = context.tool_settings
  2089. particle_edit = tool_settings.particle_edit
  2090. layout.operator("particle.rekey")
  2091. layout.separator()
  2092. layout.operator("particle.delete")
  2093. layout.separator()
  2094. layout.operator("particle.remove_doubles")
  2095. layout.operator("particle.unify_length")
  2096. if particle_edit.select_mode == 'POINT':
  2097. layout.operator("particle.subdivide")
  2098. layout.operator("particle.weight_set")
  2099. layout.separator()
  2100. layout.operator("particle.mirror")
  2101. if particle_edit.select_mode == 'POINT':
  2102. layout.separator()
  2103. layout.operator("particle.select_all", text="All").action = 'SELECT'
  2104. layout.operator("particle.select_all", text="None").action = 'DESELECT'
  2105. layout.operator("particle.select_all", text="Invert").action = 'INVERT'
  2106. layout.separator()
  2107. layout.operator("particle.select_roots")
  2108. layout.operator("particle.select_tips")
  2109. layout.separator()
  2110. layout.operator("particle.select_random")
  2111. layout.separator()
  2112. layout.operator("particle.select_more")
  2113. layout.operator("particle.select_less")
  2114. layout.separator()
  2115. layout.operator("particle.select_linked")
  2116. class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu):
  2117. _operator_name = "particle"
  2118. class VIEW3D_MT_pose(Menu):
  2119. bl_label = "Pose"
  2120. def draw(self, _context):
  2121. layout = self.layout
  2122. layout.menu("VIEW3D_MT_transform_armature")
  2123. layout.menu("VIEW3D_MT_pose_transform")
  2124. layout.menu("VIEW3D_MT_pose_apply")
  2125. layout.menu("VIEW3D_MT_snap")
  2126. layout.separator()
  2127. layout.menu("VIEW3D_MT_object_animation")
  2128. layout.separator()
  2129. layout.menu("VIEW3D_MT_pose_slide")
  2130. layout.menu("VIEW3D_MT_pose_propagate")
  2131. layout.separator()
  2132. layout.operator("pose.copy", icon='COPYDOWN')
  2133. layout.operator("pose.paste", icon='PASTEDOWN').flipped = False
  2134. layout.operator("pose.paste", icon='PASTEFLIPDOWN', text="Paste Pose Flipped").flipped = True
  2135. layout.separator()
  2136. layout.menu("VIEW3D_MT_pose_library")
  2137. layout.menu("VIEW3D_MT_pose_motion")
  2138. layout.menu("VIEW3D_MT_pose_group")
  2139. layout.separator()
  2140. layout.menu("VIEW3D_MT_object_parent")
  2141. layout.menu("VIEW3D_MT_pose_ik")
  2142. layout.menu("VIEW3D_MT_pose_constraints")
  2143. layout.separator()
  2144. layout.operator_context = 'EXEC_AREA'
  2145. layout.operator("pose.autoside_names", text="AutoName Left/Right").axis = 'XAXIS'
  2146. layout.operator("pose.autoside_names", text="AutoName Front/Back").axis = 'YAXIS'
  2147. layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS'
  2148. layout.operator("pose.flip_names")
  2149. layout.operator("pose.quaternions_flip")
  2150. layout.separator()
  2151. layout.operator_context = 'INVOKE_AREA'
  2152. layout.operator("armature.armature_layers", text="Change Armature Layers...")
  2153. layout.operator("pose.bone_layers", text="Change Bone Layers...")
  2154. layout.separator()
  2155. layout.menu("VIEW3D_MT_pose_showhide")
  2156. layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
  2157. class VIEW3D_MT_pose_transform(Menu):
  2158. bl_label = "Clear Transform"
  2159. def draw(self, _context):
  2160. layout = self.layout
  2161. layout.operator("pose.transforms_clear", text="All")
  2162. layout.separator()
  2163. layout.operator("pose.loc_clear", text="Location")
  2164. layout.operator("pose.rot_clear", text="Rotation")
  2165. layout.operator("pose.scale_clear", text="Scale")
  2166. layout.separator()
  2167. layout.operator("pose.user_transforms_clear", text="Reset Unkeyed")
  2168. class VIEW3D_MT_pose_slide(Menu):
  2169. bl_label = "In-Betweens"
  2170. def draw(self, _context):
  2171. layout = self.layout
  2172. layout.operator("pose.push_rest")
  2173. layout.operator("pose.relax_rest")
  2174. layout.operator("pose.push")
  2175. layout.operator("pose.relax")
  2176. layout.operator("pose.breakdown")
  2177. class VIEW3D_MT_pose_propagate(Menu):
  2178. bl_label = "Propagate"
  2179. def draw(self, _context):
  2180. layout = self.layout
  2181. layout.operator("pose.propagate").mode = 'WHILE_HELD'
  2182. layout.separator()
  2183. layout.operator("pose.propagate", text="To Next Keyframe").mode = 'NEXT_KEY'
  2184. layout.operator("pose.propagate", text="To Last Keyframe (Make Cyclic)").mode = 'LAST_KEY'
  2185. layout.separator()
  2186. layout.operator("pose.propagate", text="On Selected Keyframes").mode = 'SELECTED_KEYS'
  2187. layout.separator()
  2188. layout.operator("pose.propagate", text="On Selected Markers").mode = 'SELECTED_MARKERS'
  2189. class VIEW3D_MT_pose_library(Menu):
  2190. bl_label = "Pose Library"
  2191. def draw(self, _context):
  2192. layout = self.layout
  2193. layout.operator("poselib.browse_interactive", text="Browse Poses...")
  2194. layout.separator()
  2195. layout.operator("poselib.pose_add", text="Add Pose...")
  2196. layout.operator("poselib.pose_rename", text="Rename Pose...")
  2197. layout.operator("poselib.pose_remove", text="Remove Pose...")
  2198. class VIEW3D_MT_pose_motion(Menu):
  2199. bl_label = "Motion Paths"
  2200. def draw(self, _context):
  2201. layout = self.layout
  2202. layout.operator("pose.paths_calculate", text="Calculate")
  2203. layout.operator("pose.paths_clear", text="Clear")
  2204. class VIEW3D_MT_pose_group(Menu):
  2205. bl_label = "Bone Groups"
  2206. def draw(self, context):
  2207. layout = self.layout
  2208. pose = context.active_object.pose
  2209. layout.operator_context = 'EXEC_AREA'
  2210. layout.operator("pose.group_assign", text="Assign to New Group").type = 0
  2211. if pose.bone_groups:
  2212. active_group = pose.bone_groups.active_index + 1
  2213. layout.operator("pose.group_assign", text="Assign to Group").type = active_group
  2214. layout.separator()
  2215. # layout.operator_context = 'INVOKE_AREA'
  2216. layout.operator("pose.group_unassign")
  2217. layout.operator("pose.group_remove")
  2218. class VIEW3D_MT_pose_ik(Menu):
  2219. bl_label = "Inverse Kinematics"
  2220. def draw(self, _context):
  2221. layout = self.layout
  2222. layout.operator("pose.ik_add")
  2223. layout.operator("pose.ik_clear")
  2224. class VIEW3D_MT_pose_constraints(Menu):
  2225. bl_label = "Constraints"
  2226. def draw(self, _context):
  2227. layout = self.layout
  2228. layout.operator("pose.constraint_add_with_targets", text="Add (With Targets)...")
  2229. layout.operator("pose.constraints_copy")
  2230. layout.operator("pose.constraints_clear")
  2231. class VIEW3D_MT_pose_showhide(ShowHideMenu, Menu):
  2232. _operator_name = "pose"
  2233. class VIEW3D_MT_pose_apply(Menu):
  2234. bl_label = "Apply"
  2235. def draw(self, _context):
  2236. layout = self.layout
  2237. layout.operator("pose.armature_apply").selected = False
  2238. layout.operator("pose.armature_apply", text="Apply Selected as Rest Pose").selected = True
  2239. layout.operator("pose.visual_transform_apply")
  2240. layout.separator()
  2241. props = layout.operator("object.assign_property_defaults")
  2242. props.process_bones = True
  2243. class VIEW3D_MT_pose_context_menu(Menu):
  2244. bl_label = "Pose Context Menu"
  2245. def draw(self, _context):
  2246. layout = self.layout
  2247. layout.operator_context = 'INVOKE_REGION_WIN'
  2248. layout.operator("anim.keyframe_insert_menu", text="Insert Keyframe...")
  2249. layout.separator()
  2250. layout.operator("pose.copy", icon='COPYDOWN')
  2251. layout.operator("pose.paste", icon='PASTEDOWN').flipped = False
  2252. layout.operator("pose.paste", icon='PASTEFLIPDOWN', text="Paste X-Flipped Pose").flipped = True
  2253. layout.separator()
  2254. props = layout.operator("wm.call_panel", text="Rename Active Bone...")
  2255. props.name = "TOPBAR_PT_name"
  2256. props.keep_open = False
  2257. layout.separator()
  2258. layout.operator("pose.push")
  2259. layout.operator("pose.relax")
  2260. layout.operator("pose.breakdown")
  2261. layout.separator()
  2262. layout.operator("pose.paths_calculate", text="Calculate Motion Paths")
  2263. layout.operator("pose.paths_clear", text="Clear Motion Paths")
  2264. layout.separator()
  2265. layout.operator("pose.hide").unselected = False
  2266. layout.operator("pose.reveal")
  2267. layout.separator()
  2268. layout.operator("pose.user_transforms_clear")
  2269. class BoneOptions:
  2270. def draw(self, context):
  2271. layout = self.layout
  2272. options = [
  2273. "show_wire",
  2274. "use_deform",
  2275. "use_envelope_multiply",
  2276. "use_inherit_rotation",
  2277. "use_inherit_scale",
  2278. ]
  2279. if context.mode == 'EDIT_ARMATURE':
  2280. bone_props = bpy.types.EditBone.bl_rna.properties
  2281. data_path_iter = "selected_bones"
  2282. opt_suffix = ""
  2283. options.append("lock")
  2284. else: # pose-mode
  2285. bone_props = bpy.types.Bone.bl_rna.properties
  2286. data_path_iter = "selected_pose_bones"
  2287. opt_suffix = "bone."
  2288. for opt in options:
  2289. props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name,
  2290. text_ctxt=i18n_contexts.default)
  2291. props.data_path_iter = data_path_iter
  2292. props.data_path_item = opt_suffix + opt
  2293. props.type = self.type
  2294. class VIEW3D_MT_bone_options_toggle(Menu, BoneOptions):
  2295. bl_label = "Toggle Bone Options"
  2296. type = 'TOGGLE'
  2297. class VIEW3D_MT_bone_options_enable(Menu, BoneOptions):
  2298. bl_label = "Enable Bone Options"
  2299. type = 'ENABLE'
  2300. class VIEW3D_MT_bone_options_disable(Menu, BoneOptions):
  2301. bl_label = "Disable Bone Options"
  2302. type = 'DISABLE'
  2303. # ********** Edit Menus, suffix from ob.type **********
  2304. class VIEW3D_MT_edit_mesh(Menu):
  2305. bl_label = "Mesh"
  2306. def draw(self, _context):
  2307. layout = self.layout
  2308. with_bullet = bpy.app.build_options.bullet
  2309. layout.menu("VIEW3D_MT_transform")
  2310. layout.menu("VIEW3D_MT_mirror")
  2311. layout.menu("VIEW3D_MT_snap")
  2312. layout.separator()
  2313. layout.operator("mesh.duplicate_move", text="Duplicate")
  2314. layout.menu("VIEW3D_MT_edit_mesh_extrude")
  2315. layout.operator("mesh.split")
  2316. layout.operator("mesh.bisect")
  2317. layout.operator("mesh.knife_project")
  2318. if with_bullet:
  2319. layout.operator("mesh.convex_hull")
  2320. layout.separator()
  2321. layout.operator("mesh.symmetrize")
  2322. layout.operator("mesh.symmetry_snap")
  2323. layout.separator()
  2324. layout.menu("VIEW3D_MT_edit_mesh_normals")
  2325. layout.menu("VIEW3D_MT_edit_mesh_shading")
  2326. layout.menu("VIEW3D_MT_edit_mesh_weights")
  2327. layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")
  2328. layout.separator()
  2329. layout.menu("VIEW3D_MT_edit_mesh_showhide")
  2330. layout.operator_menu_enum("mesh.separate", "type")
  2331. layout.menu("VIEW3D_MT_edit_mesh_clean")
  2332. layout.separator()
  2333. layout.menu("VIEW3D_MT_edit_mesh_delete")
  2334. class VIEW3D_MT_edit_mesh_context_menu(Menu):
  2335. bl_label = ""
  2336. def draw(self, context):
  2337. def count_selected_items_for_objects_in_mode():
  2338. selected_verts_len = 0
  2339. selected_edges_len = 0
  2340. selected_faces_len = 0
  2341. for ob in context.objects_in_mode_unique_data:
  2342. v, e, f = ob.data.count_selected_items()
  2343. selected_verts_len += v
  2344. selected_edges_len += e
  2345. selected_faces_len += f
  2346. return (selected_verts_len, selected_edges_len, selected_faces_len)
  2347. is_vert_mode, is_edge_mode, is_face_mode = context.tool_settings.mesh_select_mode
  2348. selected_verts_len, selected_edges_len, selected_faces_len = count_selected_items_for_objects_in_mode()
  2349. del count_selected_items_for_objects_in_mode
  2350. layout = self.layout
  2351. layout.operator_context = 'INVOKE_REGION_WIN'
  2352. # If nothing is selected
  2353. # (disabled for now until it can be made more useful).
  2354. '''
  2355. # If nothing is selected
  2356. if not (selected_verts_len or selected_edges_len or selected_faces_len):
  2357. layout.menu("VIEW3D_MT_mesh_add", text="Add", text_ctxt=i18n_contexts.operator_default)
  2358. return
  2359. '''
  2360. # Else something is selected
  2361. row = layout.row()
  2362. if is_vert_mode:
  2363. col = row.column()
  2364. col.label(text="Vertex Context Menu", icon='VERTEXSEL')
  2365. col.separator()
  2366. # Additive Operators
  2367. col.operator("mesh.subdivide", text="Subdivide")
  2368. col.separator()
  2369. col.operator("mesh.extrude_vertices_move", text="Extrude Vertices")
  2370. col.operator("mesh.bevel", text="Bevel Vertices").vertex_only = True
  2371. if selected_verts_len > 1:
  2372. col.separator()
  2373. col.operator("mesh.edge_face_add", text="New Edge/Face from Vertices")
  2374. col.operator("mesh.vert_connect_path", text="Connect Vertex Path")
  2375. col.operator("mesh.vert_connect", text="Connect Vertex Pairs")
  2376. col.separator()
  2377. # Deform Operators
  2378. col.operator("transform.push_pull", text="Push/Pull")
  2379. col.operator("transform.shrink_fatten", text="Shrink/Fatten")
  2380. col.operator("transform.shear", text="Shear")
  2381. col.operator("transform.vert_slide", text="Slide Vertices")
  2382. col.operator("transform.vertex_random", text="Randomize Vertices")
  2383. col.operator("mesh.vertices_smooth", text="Smooth Vertices")
  2384. col.operator("mesh.vertices_smooth_laplacian", text="Smooth Laplacian")
  2385. col.separator()
  2386. col.menu("VIEW3D_MT_mirror", text="Mirror Vertices")
  2387. col.menu("VIEW3D_MT_snap", text="Snap Vertices")
  2388. col.separator()
  2389. # Removal Operators
  2390. if selected_verts_len > 1:
  2391. col.menu("VIEW3D_MT_edit_mesh_merge", text="Merge Vertices")
  2392. col.operator("mesh.split")
  2393. col.operator_menu_enum("mesh.separate", "type")
  2394. col.operator("mesh.dissolve_verts")
  2395. col.operator("mesh.delete", text="Delete Vertices").type = 'VERT'
  2396. if is_edge_mode:
  2397. render = context.scene.render
  2398. col = row.column()
  2399. col.label(text="Edge Context Menu", icon='EDGESEL')
  2400. col.separator()
  2401. # Additive Operators
  2402. col.operator("mesh.subdivide", text="Subdivide")
  2403. col.separator()
  2404. col.operator("mesh.extrude_edges_move", text="Extrude Edges")
  2405. col.operator("mesh.bevel", text="Bevel Edges").vertex_only = False
  2406. if selected_edges_len >= 2:
  2407. col.operator("mesh.bridge_edge_loops")
  2408. if selected_edges_len >= 1:
  2409. col.operator("mesh.edge_face_add", text="New Face from Edges")
  2410. if selected_edges_len >= 2:
  2411. col.operator("mesh.fill")
  2412. col.separator()
  2413. col.operator("mesh.loopcut_slide")
  2414. col.operator("mesh.offset_edge_loops_slide")
  2415. col.operator("mesh.knife_tool")
  2416. col.operator("mesh.bisect")
  2417. col.operator("mesh.bridge_edge_loops", text="Bridge Edge Loops")
  2418. col.separator()
  2419. # Deform Operators
  2420. col.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False
  2421. col.operator("transform.edge_slide")
  2422. col.operator("mesh.edge_split")
  2423. col.separator()
  2424. # Edge Flags
  2425. col.operator("transform.edge_crease")
  2426. col.operator("transform.edge_bevelweight")
  2427. col.separator()
  2428. col.operator("mesh.mark_seam").clear = False
  2429. col.operator("mesh.mark_seam", text="Clear Seam").clear = True
  2430. col.separator()
  2431. col.operator("mesh.mark_sharp")
  2432. col.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
  2433. if render.use_freestyle:
  2434. col.separator()
  2435. col.operator("mesh.mark_freestyle_edge").clear = False
  2436. col.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
  2437. col.separator()
  2438. # Removal Operators
  2439. col.operator("mesh.unsubdivide")
  2440. col.operator("mesh.split")
  2441. col.operator_menu_enum("mesh.separate", "type")
  2442. col.operator("mesh.dissolve_edges")
  2443. col.operator("mesh.delete", text="Delete Edges").type = 'EDGE'
  2444. if is_face_mode:
  2445. col = row.column()
  2446. col.label(text="Face Context Menu", icon='FACESEL')
  2447. col.separator()
  2448. # Additive Operators
  2449. col.operator("mesh.subdivide", text="Subdivide")
  2450. col.separator()
  2451. col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces")
  2452. col.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals")
  2453. col.operator("mesh.extrude_faces_move", text="Extrude Individual Faces")
  2454. col.operator("mesh.inset")
  2455. col.operator("mesh.poke")
  2456. if selected_faces_len >= 2:
  2457. col.operator("mesh.bridge_edge_loops", text="Bridge Faces")
  2458. col.separator()
  2459. # Modify Operators
  2460. col.menu("VIEW3D_MT_uv_map", text="UV Unwrap Faces")
  2461. col.separator()
  2462. props = col.operator("mesh.quads_convert_to_tris")
  2463. props.quad_method = props.ngon_method = 'BEAUTY'
  2464. col.operator("mesh.tris_convert_to_quads")
  2465. col.separator()
  2466. col.operator("mesh.faces_shade_smooth")
  2467. col.operator("mesh.faces_shade_flat")
  2468. col.separator()
  2469. # Removal Operators
  2470. col.operator("mesh.unsubdivide")
  2471. col.operator("mesh.split")
  2472. col.operator_menu_enum("mesh.separate", "type")
  2473. col.operator("mesh.dissolve_faces")
  2474. col.operator("mesh.delete", text="Delete Faces").type = 'FACE'
  2475. class VIEW3D_MT_edit_mesh_select_mode(Menu):
  2476. bl_label = "Mesh Select Mode"
  2477. def draw(self, _context):
  2478. layout = self.layout
  2479. layout.operator_context = 'INVOKE_REGION_WIN'
  2480. layout.operator("mesh.select_mode", text="Vertex", icon='VERTEXSEL').type = 'VERT'
  2481. layout.operator("mesh.select_mode", text="Edge", icon='EDGESEL').type = 'EDGE'
  2482. layout.operator("mesh.select_mode", text="Face", icon='FACESEL').type = 'FACE'
  2483. class VIEW3D_MT_edit_mesh_extrude(Menu):
  2484. bl_label = "Extrude"
  2485. _extrude_funcs = {
  2486. 'VERT': lambda layout:
  2487. layout.operator("mesh.extrude_vertices_move", text="Extrude Vertices"),
  2488. 'EDGE': lambda layout:
  2489. layout.operator("mesh.extrude_edges_move", text="Extrude Edges"),
  2490. 'REGION': lambda layout:
  2491. layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces"),
  2492. 'REGION_VERT_NORMAL': lambda layout:
  2493. layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals"),
  2494. 'FACE': lambda layout:
  2495. layout.operator("mesh.extrude_faces_move", text="Extrude Individual Faces"),
  2496. }
  2497. @staticmethod
  2498. def extrude_options(context):
  2499. tool_settings = context.tool_settings
  2500. select_mode = tool_settings.mesh_select_mode
  2501. mesh = context.object.data
  2502. menu = []
  2503. if mesh.total_face_sel:
  2504. menu += ['REGION', 'REGION_VERT_NORMAL', 'FACE']
  2505. if mesh.total_edge_sel and (select_mode[0] or select_mode[1]):
  2506. menu += ['EDGE']
  2507. if mesh.total_vert_sel and select_mode[0]:
  2508. menu += ['VERT']
  2509. # should never get here
  2510. return menu
  2511. def draw(self, context):
  2512. layout = self.layout
  2513. layout.operator_context = 'INVOKE_REGION_WIN'
  2514. for menu_id in self.extrude_options(context):
  2515. self._extrude_funcs[menu_id](layout)
  2516. class VIEW3D_MT_edit_mesh_vertices(Menu):
  2517. bl_label = "Vertex"
  2518. def draw(self, _context):
  2519. layout = self.layout
  2520. layout.operator_context = 'INVOKE_REGION_WIN'
  2521. layout.operator("mesh.extrude_vertices_move", text="Extrude Vertices")
  2522. layout.operator("mesh.bevel", text="Bevel Vertices").vertex_only = True
  2523. layout.separator()
  2524. layout.operator("mesh.edge_face_add", text="New Edge/Face from Vertices")
  2525. layout.operator("mesh.vert_connect_path", text="Connect Vertex Path")
  2526. layout.operator("mesh.vert_connect", text="Connect Vertex Pairs")
  2527. layout.separator()
  2528. props = layout.operator("mesh.rip_move", text="Rip Vertices")
  2529. props.MESH_OT_rip.use_fill = False
  2530. props = layout.operator("mesh.rip_move", text="Rip Vertices and Fill")
  2531. props.MESH_OT_rip.use_fill = True
  2532. layout.operator("mesh.rip_edge_move", text="Rip Vertices and Extend")
  2533. layout.separator()
  2534. layout.operator("transform.vert_slide", text="Slide Vertices")
  2535. layout.operator("mesh.vertices_smooth", text="Smooth Vertices")
  2536. layout.separator()
  2537. layout.operator("mesh.blend_from_shape")
  2538. layout.operator("mesh.shape_propagate_to_all", text="Propagate to Shapes")
  2539. layout.separator()
  2540. layout.menu("VIEW3D_MT_edit_mesh_merge", text="Merge Vertices")
  2541. layout.separator()
  2542. layout.menu("VIEW3D_MT_vertex_group")
  2543. layout.menu("VIEW3D_MT_hook")
  2544. layout.separator()
  2545. layout.operator("object.vertex_parent_set")
  2546. class VIEW3D_MT_edit_mesh_edges_data(Menu):
  2547. bl_label = "Edge Data"
  2548. def draw(self, context):
  2549. layout = self.layout
  2550. render = context.scene.render
  2551. layout.operator_context = 'INVOKE_REGION_WIN'
  2552. layout.operator("transform.edge_crease")
  2553. layout.operator("transform.edge_bevelweight")
  2554. layout.separator()
  2555. layout.operator("mesh.mark_seam").clear = False
  2556. layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
  2557. layout.separator()
  2558. layout.operator("mesh.mark_sharp")
  2559. layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
  2560. layout.operator("mesh.mark_sharp", text="Mark Sharp from Vertices").use_verts = True
  2561. props = layout.operator("mesh.mark_sharp", text="Clear Sharp from Vertices")
  2562. props.use_verts = True
  2563. props.clear = True
  2564. if render.use_freestyle:
  2565. layout.separator()
  2566. layout.operator("mesh.mark_freestyle_edge").clear = False
  2567. layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
  2568. class VIEW3D_MT_edit_mesh_edges(Menu):
  2569. bl_label = "Edge"
  2570. def draw(self, _context):
  2571. layout = self.layout
  2572. with_freestyle = bpy.app.build_options.freestyle
  2573. layout.operator_context = 'INVOKE_REGION_WIN'
  2574. layout.operator("mesh.extrude_edges_move", text="Extrude Edges")
  2575. layout.operator("mesh.bevel", text="Bevel Edges").vertex_only = False
  2576. layout.operator("mesh.bridge_edge_loops")
  2577. layout.separator()
  2578. layout.operator("mesh.subdivide")
  2579. layout.operator("mesh.subdivide_edgering")
  2580. layout.operator("mesh.unsubdivide")
  2581. layout.separator()
  2582. layout.operator("mesh.edge_rotate", text="Rotate Edge CW").use_ccw = False
  2583. layout.operator("mesh.edge_rotate", text="Rotate Edge CCW").use_ccw = True
  2584. layout.separator()
  2585. layout.operator("transform.edge_slide")
  2586. layout.operator("mesh.edge_split")
  2587. layout.separator()
  2588. layout.operator("transform.edge_crease")
  2589. layout.operator("transform.edge_bevelweight")
  2590. layout.separator()
  2591. layout.operator("mesh.mark_seam").clear = False
  2592. layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
  2593. layout.separator()
  2594. layout.operator("mesh.mark_sharp")
  2595. layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
  2596. layout.operator("mesh.mark_sharp", text="Mark Sharp from Vertices").use_verts = True
  2597. props = layout.operator("mesh.mark_sharp", text="Clear Sharp from Vertices")
  2598. props.use_verts = True
  2599. props.clear = True
  2600. if with_freestyle:
  2601. layout.separator()
  2602. layout.operator("mesh.mark_freestyle_edge").clear = False
  2603. layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
  2604. class VIEW3D_MT_edit_mesh_faces_data(Menu):
  2605. bl_label = "Face Data"
  2606. def draw(self, _context):
  2607. layout = self.layout
  2608. with_freestyle = bpy.app.build_options.freestyle
  2609. layout.operator_context = 'INVOKE_REGION_WIN'
  2610. layout.operator("mesh.colors_rotate")
  2611. layout.operator("mesh.colors_reverse")
  2612. layout.separator()
  2613. layout.operator("mesh.uvs_rotate")
  2614. layout.operator("mesh.uvs_reverse")
  2615. layout.separator()
  2616. if with_freestyle:
  2617. layout.operator("mesh.mark_freestyle_face").clear = False
  2618. layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True
  2619. class VIEW3D_MT_edit_mesh_faces(Menu):
  2620. bl_label = "Face"
  2621. bl_idname = "VIEW3D_MT_edit_mesh_faces"
  2622. def draw(self, _context):
  2623. layout = self.layout
  2624. layout.operator_context = 'INVOKE_REGION_WIN'
  2625. layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces")
  2626. layout.operator("view3d.edit_mesh_extrude_move_shrink_fatten", text="Extrude Faces Along Normals")
  2627. layout.operator("mesh.extrude_faces_move", text="Extrude Individual Faces")
  2628. layout.separator()
  2629. layout.operator("mesh.inset")
  2630. layout.operator("mesh.poke")
  2631. props = layout.operator("mesh.quads_convert_to_tris")
  2632. props.quad_method = props.ngon_method = 'BEAUTY'
  2633. layout.operator("mesh.tris_convert_to_quads")
  2634. layout.operator("mesh.solidify", text="Solidify Faces")
  2635. layout.operator("mesh.wireframe")
  2636. layout.separator()
  2637. layout.operator("mesh.fill")
  2638. layout.operator("mesh.fill_grid")
  2639. layout.operator("mesh.beautify_fill")
  2640. layout.separator()
  2641. layout.operator("mesh.intersect")
  2642. layout.operator("mesh.intersect_boolean")
  2643. layout.separator()
  2644. layout.operator("mesh.face_split_by_edges")
  2645. layout.separator()
  2646. layout.operator("mesh.faces_shade_smooth")
  2647. layout.operator("mesh.faces_shade_flat")
  2648. layout.separator()
  2649. layout.menu("VIEW3D_MT_edit_mesh_faces_data")
  2650. class VIEW3D_MT_edit_mesh_normals_select_strength(Menu):
  2651. bl_label = "Select by Face Strength"
  2652. def draw(self, _context):
  2653. layout = self.layout
  2654. op = layout.operator("mesh.mod_weighted_strength", text="Weak")
  2655. op.set = False
  2656. op.face_strength = 'WEAK'
  2657. op = layout.operator("mesh.mod_weighted_strength", text="Medium")
  2658. op.set = False
  2659. op.face_strength = 'MEDIUM'
  2660. op = layout.operator("mesh.mod_weighted_strength", text="Strong")
  2661. op.set = False
  2662. op.face_strength = 'STRONG'
  2663. class VIEW3D_MT_edit_mesh_normals_set_strength(Menu):
  2664. bl_label = "Select by Face Strength"
  2665. def draw(self, _context):
  2666. layout = self.layout
  2667. op = layout.operator("mesh.mod_weighted_strength", text="Weak")
  2668. op.set = True
  2669. op.face_strength = 'WEAK'
  2670. op = layout.operator("mesh.mod_weighted_strength", text="Medium")
  2671. op.set = True
  2672. op.face_strength = 'MEDIUM'
  2673. op = layout.operator("mesh.mod_weighted_strength", text="Strong")
  2674. op.set = True
  2675. op.face_strength = 'STRONG'
  2676. class VIEW3D_MT_edit_mesh_normals_average(Menu):
  2677. bl_label = "Average"
  2678. def draw(self, _context):
  2679. layout = self.layout
  2680. layout.operator("mesh.average_normals", text="Custom Normal").average_type = 'CUSTOM_NORMAL'
  2681. layout.operator("mesh.average_normals", text="Face Area").average_type = 'FACE_AREA'
  2682. layout.operator("mesh.average_normals", text="Corner Angle").average_type = 'CORNER_ANGLE'
  2683. class VIEW3D_MT_edit_mesh_normals(Menu):
  2684. bl_label = "Normals"
  2685. def draw(self, _context):
  2686. layout = self.layout
  2687. layout.operator("mesh.flip_normals", text="Flip")
  2688. layout.operator("mesh.normals_make_consistent", text="Recalculate Outside").inside = False
  2689. layout.operator("mesh.normals_make_consistent", text="Recalculate Inside").inside = True
  2690. layout.separator()
  2691. layout.operator("mesh.set_normals_from_faces", text="Set From Faces")
  2692. layout.operator_context = 'INVOKE_DEFAULT'
  2693. layout.operator("transform.rotate_normal", text="Rotate...")
  2694. layout.operator("mesh.point_normals", text="Point to Target...")
  2695. layout.operator_context = 'EXEC_DEFAULT'
  2696. layout.operator("mesh.merge_normals", text="Merge")
  2697. layout.operator("mesh.split_normals", text="Split")
  2698. layout.menu("VIEW3D_MT_edit_mesh_normals_average", text="Average")
  2699. layout.separator()
  2700. layout.operator("mesh.normals_tools", text="Copy Vectors").mode = 'COPY'
  2701. layout.operator("mesh.normals_tools", text="Paste Vectors").mode = 'PASTE'
  2702. layout.operator("mesh.smoothen_normals", text="Smoothen Vectors")
  2703. layout.operator("mesh.normals_tools", text="Reset Vectors").mode = 'RESET'
  2704. layout.separator()
  2705. layout.menu("VIEW3D_MT_edit_mesh_normals_select_strength", text="Select by Face Strength")
  2706. layout.menu("VIEW3D_MT_edit_mesh_normals_set_strength", text="Set Face Strength")
  2707. class VIEW3D_MT_edit_mesh_shading(Menu):
  2708. bl_label = "Shading"
  2709. def draw(self, _context):
  2710. layout = self.layout
  2711. layout.operator("mesh.faces_shade_smooth", text="Smooth Faces")
  2712. layout.operator("mesh.faces_shade_flat", text="Flat Faces")
  2713. layout.separator()
  2714. layout.operator("mesh.mark_sharp", text="Smooth Edges").clear = True
  2715. layout.operator("mesh.mark_sharp", text="Sharp Edges")
  2716. layout.separator()
  2717. props = layout.operator("mesh.mark_sharp", text="Smooth Vertices")
  2718. props.use_verts = True
  2719. props.clear = True
  2720. layout.operator("mesh.mark_sharp", text="Sharp Vertices").use_verts = True
  2721. class VIEW3D_MT_edit_mesh_weights(Menu):
  2722. bl_label = "Weights"
  2723. def draw(self, _context):
  2724. VIEW3D_MT_paint_weight.draw_generic(self.layout, is_editmode=True)
  2725. class VIEW3D_MT_edit_mesh_clean(Menu):
  2726. bl_label = "Clean Up"
  2727. def draw(self, _context):
  2728. layout = self.layout
  2729. layout.operator("mesh.delete_loose")
  2730. layout.separator()
  2731. layout.operator("mesh.decimate")
  2732. layout.operator("mesh.dissolve_degenerate")
  2733. layout.operator("mesh.dissolve_limited")
  2734. layout.operator("mesh.face_make_planar")
  2735. layout.separator()
  2736. layout.operator("mesh.vert_connect_nonplanar")
  2737. layout.operator("mesh.vert_connect_concave")
  2738. layout.operator("mesh.remove_doubles")
  2739. layout.operator("mesh.fill_holes")
  2740. class VIEW3D_MT_edit_mesh_delete(Menu):
  2741. bl_label = "Delete"
  2742. def draw(self, _context):
  2743. layout = self.layout
  2744. layout.operator_enum("mesh.delete", "type")
  2745. layout.separator()
  2746. layout.operator("mesh.dissolve_verts")
  2747. layout.operator("mesh.dissolve_edges")
  2748. layout.operator("mesh.dissolve_faces")
  2749. layout.separator()
  2750. layout.operator("mesh.dissolve_limited")
  2751. layout.separator()
  2752. layout.operator("mesh.edge_collapse")
  2753. layout.operator("mesh.delete_edgeloop", text="Edge Loops")
  2754. class VIEW3D_MT_edit_mesh_merge(Menu):
  2755. bl_label = "Merge"
  2756. def draw(self, _context):
  2757. layout = self.layout
  2758. layout.operator_enum("mesh.merge", "type")
  2759. layout.separator()
  2760. layout.operator("mesh.remove_doubles", text="By Distance")
  2761. class VIEW3D_MT_edit_mesh_showhide(ShowHideMenu, Menu):
  2762. _operator_name = "mesh"
  2763. class VIEW3D_MT_edit_gpencil_delete(Menu):
  2764. bl_label = "Delete"
  2765. def draw(self, _context):
  2766. layout = self.layout
  2767. layout.operator_enum("gpencil.delete", "type")
  2768. layout.separator()
  2769. layout.operator_enum("gpencil.dissolve", "type")
  2770. layout.separator()
  2771. layout.operator("gpencil.active_frames_delete_all")
  2772. # Edit Curve
  2773. # draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface
  2774. def draw_curve(self, _context):
  2775. layout = self.layout
  2776. layout.menu("VIEW3D_MT_transform")
  2777. layout.menu("VIEW3D_MT_mirror")
  2778. layout.menu("VIEW3D_MT_snap")
  2779. layout.separator()
  2780. layout.operator("curve.spin")
  2781. layout.operator("curve.duplicate_move")
  2782. layout.separator()
  2783. layout.operator("curve.split")
  2784. layout.operator("curve.separate")
  2785. layout.operator("curve.cyclic_toggle")
  2786. layout.operator_menu_enum("curve.spline_type_set", "type")
  2787. layout.separator()
  2788. layout.menu("VIEW3D_MT_edit_curve_showhide")
  2789. layout.menu("VIEW3D_MT_edit_curve_clean")
  2790. layout.menu("VIEW3D_MT_edit_curve_delete")
  2791. class VIEW3D_MT_edit_curve(Menu):
  2792. bl_label = "Curve"
  2793. draw = draw_curve
  2794. class VIEW3D_MT_edit_curve_ctrlpoints(Menu):
  2795. bl_label = "Control Points"
  2796. def draw(self, context):
  2797. layout = self.layout
  2798. edit_object = context.edit_object
  2799. if edit_object.type in {'CURVE', 'SURFACE'}:
  2800. layout.operator("curve.extrude_move")
  2801. layout.separator()
  2802. layout.operator("curve.make_segment")
  2803. layout.separator()
  2804. if edit_object.type == 'CURVE':
  2805. layout.operator("transform.tilt")
  2806. layout.operator("curve.tilt_clear")
  2807. layout.separator()
  2808. layout.operator_menu_enum("curve.handle_type_set", "type")
  2809. layout.operator("curve.normals_make_consistent")
  2810. layout.separator()
  2811. layout.operator("curve.smooth")
  2812. if edit_object.type == 'CURVE':
  2813. layout.operator("curve.smooth_tilt")
  2814. layout.operator("curve.smooth_radius")
  2815. layout.operator("curve.smooth_weight")
  2816. layout.separator()
  2817. layout.menu("VIEW3D_MT_hook")
  2818. layout.separator()
  2819. layout.operator("object.vertex_parent_set")
  2820. class VIEW3D_MT_edit_curve_segments(Menu):
  2821. bl_label = "Segments"
  2822. def draw(self, _context):
  2823. layout = self.layout
  2824. layout.operator("curve.subdivide")
  2825. layout.operator("curve.switch_direction")
  2826. class VIEW3D_MT_edit_curve_clean(Menu):
  2827. bl_label = "Clean Up"
  2828. def draw(self, _context):
  2829. layout = self.layout
  2830. layout.operator("curve.decimate")
  2831. class VIEW3D_MT_edit_curve_context_menu(Menu):
  2832. bl_label = "Curve Context Menu"
  2833. def draw(self, _context):
  2834. # TODO(campbell): match mesh vertex menu.
  2835. layout = self.layout
  2836. layout.operator_context = 'INVOKE_DEFAULT'
  2837. # Add
  2838. layout.operator("curve.subdivide")
  2839. layout.operator("curve.extrude_move")
  2840. layout.operator("curve.make_segment")
  2841. layout.operator("curve.duplicate_move")
  2842. layout.separator()
  2843. # Transform
  2844. layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
  2845. layout.operator("transform.tilt")
  2846. layout.operator("curve.tilt_clear")
  2847. layout.operator("curve.smooth")
  2848. layout.operator("curve.smooth_tilt")
  2849. layout.operator("curve.smooth_radius")
  2850. layout.separator()
  2851. layout.menu("VIEW3D_MT_mirror")
  2852. layout.menu("VIEW3D_MT_snap")
  2853. layout.separator()
  2854. # Modify
  2855. layout.operator_menu_enum("curve.spline_type_set", "type")
  2856. layout.operator_menu_enum("curve.handle_type_set", "type")
  2857. layout.operator("curve.cyclic_toggle")
  2858. layout.operator("curve.switch_direction")
  2859. layout.separator()
  2860. layout.operator("curve.normals_make_consistent")
  2861. layout.operator("curve.spline_weight_set")
  2862. layout.operator("curve.radius_set")
  2863. layout.separator()
  2864. # Remove
  2865. layout.operator("curve.split")
  2866. layout.operator("curve.decimate")
  2867. layout.operator("curve.dissolve_verts")
  2868. layout.operator("curve.delete", text="Delete Segment").type = 'SEGMENT'
  2869. layout.operator("curve.delete", text="Delete Point").type = 'VERT'
  2870. class VIEW3D_MT_edit_curve_delete(Menu):
  2871. bl_label = "Delete"
  2872. def draw(self, _context):
  2873. layout = self.layout
  2874. layout.operator_enum("curve.delete", "type")
  2875. layout.separator()
  2876. layout.operator("curve.dissolve_verts")
  2877. class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, Menu):
  2878. _operator_name = "curve"
  2879. class VIEW3D_MT_edit_surface(Menu):
  2880. bl_label = "Surface"
  2881. draw = draw_curve
  2882. class VIEW3D_MT_edit_font(Menu):
  2883. bl_label = "Font"
  2884. def draw(self, _context):
  2885. layout = self.layout
  2886. layout.operator("font.style_toggle", text="Toggle Bold", icon='BOLD').style = 'BOLD'
  2887. layout.operator("font.style_toggle", text="Toggle Italic", icon='ITALIC').style = 'ITALIC'
  2888. layout.operator("font.style_toggle", text="Toggle Underline", icon='UNDERLINE').style = 'UNDERLINE'
  2889. layout.operator("font.style_toggle", text="Toggle Small Caps", icon='SMALL_CAPS').style = 'SMALL_CAPS'
  2890. class VIEW3D_MT_edit_text_chars(Menu):
  2891. bl_label = "Special Characters"
  2892. def draw(self, _context):
  2893. layout = self.layout
  2894. layout.operator("font.text_insert", text="Copyright").text = "\u00A9"
  2895. layout.operator("font.text_insert", text="Registered Trademark").text = "\u00AE"
  2896. layout.separator()
  2897. layout.operator("font.text_insert", text="Degree Sign").text = "\u00B0"
  2898. layout.operator("font.text_insert", text="Multiplication Sign").text = "\u00D7"
  2899. layout.operator("font.text_insert", text="Circle").text = "\u008A"
  2900. layout.separator()
  2901. layout.operator("font.text_insert", text="Superscript 1").text = "\u00B9"
  2902. layout.operator("font.text_insert", text="Superscript 2").text = "\u00B2"
  2903. layout.operator("font.text_insert", text="Superscript 3").text = "\u00B3"
  2904. layout.separator()
  2905. layout.operator("font.text_insert", text="Double >>").text = "\u00BB"
  2906. layout.operator("font.text_insert", text="Double <<").text = "\u00AB"
  2907. layout.operator("font.text_insert", text="Promillage").text = "\u2030"
  2908. layout.separator()
  2909. layout.operator("font.text_insert", text="Dutch Florin").text = "\u00A4"
  2910. layout.operator("font.text_insert", text="British Pound").text = "\u00A3"
  2911. layout.operator("font.text_insert", text="Japanese Yen").text = "\u00A5"
  2912. layout.separator()
  2913. layout.operator("font.text_insert", text="German S").text = "\u00DF"
  2914. layout.operator("font.text_insert", text="Spanish Question Mark").text = "\u00BF"
  2915. layout.operator("font.text_insert", text="Spanish Exclamation Mark").text = "\u00A1"
  2916. class VIEW3D_MT_edit_meta(Menu):
  2917. bl_label = "Metaball"
  2918. def draw(self, _context):
  2919. layout = self.layout
  2920. layout.menu("VIEW3D_MT_transform")
  2921. layout.menu("VIEW3D_MT_mirror")
  2922. layout.menu("VIEW3D_MT_snap")
  2923. layout.separator()
  2924. layout.operator("mball.duplicate_metaelems")
  2925. layout.separator()
  2926. layout.menu("VIEW3D_MT_edit_meta_showhide")
  2927. layout.operator_context = 'EXEC_DEFAULT'
  2928. layout.operator("mball.delete_metaelems", text="Delete")
  2929. class VIEW3D_MT_edit_meta_showhide(Menu):
  2930. bl_label = "Show/Hide"
  2931. def draw(self, _context):
  2932. layout = self.layout
  2933. layout.operator("mball.reveal_metaelems")
  2934. layout.operator("mball.hide_metaelems", text="Hide Selected").unselected = False
  2935. layout.operator("mball.hide_metaelems", text="Hide Unselected").unselected = True
  2936. class VIEW3D_MT_edit_lattice(Menu):
  2937. bl_label = "Lattice"
  2938. def draw(self, _context):
  2939. layout = self.layout
  2940. layout.separator()
  2941. layout.menu("VIEW3D_MT_transform")
  2942. layout.menu("VIEW3D_MT_mirror")
  2943. layout.menu("VIEW3D_MT_snap")
  2944. layout.operator_menu_enum("lattice.flip", "axis")
  2945. layout.separator()
  2946. layout.operator("lattice.make_regular")
  2947. layout.separator()
  2948. layout.operator("object.vertex_parent_set")
  2949. class VIEW3D_MT_edit_armature(Menu):
  2950. bl_label = "Armature"
  2951. def draw(self, context):
  2952. layout = self.layout
  2953. edit_object = context.edit_object
  2954. arm = edit_object.data
  2955. layout.menu("VIEW3D_MT_transform_armature")
  2956. layout.menu("VIEW3D_MT_mirror")
  2957. layout.menu("VIEW3D_MT_snap")
  2958. layout.menu("VIEW3D_MT_edit_armature_roll")
  2959. layout.separator()
  2960. layout.operator("armature.extrude_move")
  2961. if arm.use_mirror_x:
  2962. layout.operator("armature.extrude_forked")
  2963. layout.operator("armature.duplicate_move")
  2964. layout.operator("armature.merge")
  2965. layout.operator("armature.fill")
  2966. layout.operator("armature.split")
  2967. layout.operator("armature.separate")
  2968. layout.separator()
  2969. layout.operator("armature.subdivide", text="Subdivide")
  2970. layout.operator("armature.switch_direction", text="Switch Direction")
  2971. layout.separator()
  2972. layout.operator("armature.symmetrize")
  2973. layout.menu("VIEW3D_MT_edit_armature_names")
  2974. layout.separator()
  2975. layout.operator_context = 'INVOKE_DEFAULT'
  2976. layout.operator("armature.armature_layers")
  2977. layout.operator("armature.bone_layers")
  2978. layout.separator()
  2979. layout.menu("VIEW3D_MT_edit_armature_parent")
  2980. layout.separator()
  2981. layout.menu("VIEW3D_MT_bone_options_toggle", text="Bone Settings")
  2982. layout.separator()
  2983. layout.menu("VIEW3D_MT_edit_armature_delete")
  2984. class VIEW3D_MT_armature_context_menu(Menu):
  2985. bl_label = "Armature Context Menu"
  2986. def draw(self, context):
  2987. layout = self.layout
  2988. edit_object = context.edit_object
  2989. arm = edit_object.data
  2990. layout.operator_context = 'INVOKE_REGION_WIN'
  2991. # Add
  2992. layout.operator("armature.subdivide", text="Subdivide")
  2993. layout.operator("armature.duplicate_move", text="Duplicate")
  2994. layout.operator("armature.extrude_move")
  2995. if arm.use_mirror_x:
  2996. layout.operator("armature.extrude_forked")
  2997. layout.separator()
  2998. layout.operator("armature.fill")
  2999. layout.separator()
  3000. # Modify
  3001. layout.menu("VIEW3D_MT_mirror")
  3002. layout.menu("VIEW3D_MT_snap")
  3003. layout.operator("armature.symmetrize")
  3004. layout.operator("armature.switch_direction", text="Switch Direction")
  3005. layout.menu("VIEW3D_MT_edit_armature_names")
  3006. layout.separator()
  3007. layout.menu("VIEW3D_MT_edit_armature_parent")
  3008. layout.separator()
  3009. # Remove
  3010. layout.operator("armature.split")
  3011. layout.operator("armature.merge")
  3012. layout.operator("armature.dissolve")
  3013. layout.operator("armature.delete")
  3014. class VIEW3D_MT_edit_armature_names(Menu):
  3015. bl_label = "Names"
  3016. def draw(self, _context):
  3017. layout = self.layout
  3018. layout.operator_context = 'EXEC_REGION_WIN'
  3019. layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS'
  3020. layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS'
  3021. layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS'
  3022. layout.operator("armature.flip_names", text="Flip Names")
  3023. class VIEW3D_MT_edit_armature_parent(Menu):
  3024. bl_label = "Parent"
  3025. def draw(self, _context):
  3026. layout = self.layout
  3027. layout.operator("armature.parent_set", text="Make")
  3028. layout.operator("armature.parent_clear", text="Clear")
  3029. class VIEW3D_MT_edit_armature_roll(Menu):
  3030. bl_label = "Bone Roll"
  3031. def draw(self, _context):
  3032. layout = self.layout
  3033. layout.operator_menu_enum("armature.calculate_roll", "type")
  3034. layout.separator()
  3035. layout.operator("transform.transform", text="Set Roll").mode = 'BONE_ROLL'
  3036. layout.operator("armature.roll_clear")
  3037. class VIEW3D_MT_edit_armature_delete(Menu):
  3038. bl_label = "Delete"
  3039. def draw(self, _context):
  3040. layout = self.layout
  3041. layout.operator_context = 'EXEC_AREA'
  3042. layout.operator("armature.delete", text="Bones")
  3043. layout.separator()
  3044. layout.operator("armature.dissolve", text="Dissolve Bones")
  3045. # ********** Grease Pencil Stroke menus **********
  3046. class VIEW3D_MT_gpencil_autoweights(Menu):
  3047. bl_label = "Generate Weights"
  3048. def draw(self, _context):
  3049. layout = self.layout
  3050. layout.operator("gpencil.generate_weights", text="With Empty Groups").mode = 'NAME'
  3051. layout.operator("gpencil.generate_weights", text="With Automatic Weights").mode = 'AUTO'
  3052. class VIEW3D_MT_gpencil_simplify(Menu):
  3053. bl_label = "Simplify"
  3054. def draw(self, _context):
  3055. layout = self.layout
  3056. layout.operator("gpencil.stroke_simplify_fixed", text="Fixed")
  3057. layout.operator("gpencil.stroke_simplify", text="Adaptive")
  3058. class VIEW3D_MT_paint_gpencil(Menu):
  3059. bl_label = "Strokes"
  3060. def draw(self, _context):
  3061. layout = self.layout
  3062. layout.menu("VIEW3D_MT_gpencil_animation")
  3063. layout.menu("VIEW3D_MT_edit_gpencil_interpolate")
  3064. layout.separator()
  3065. layout.operator("gpencil.delete", text="Delete Frame").type = 'FRAME'
  3066. layout.operator("gpencil.active_frames_delete_all")
  3067. class VIEW3D_MT_assign_material(Menu):
  3068. bl_label = "Assign Material"
  3069. def draw(self, context):
  3070. layout = self.layout
  3071. ob = context.active_object
  3072. for slot in ob.material_slots:
  3073. mat = slot.material
  3074. if mat:
  3075. layout.operator("gpencil.stroke_change_color", text=mat.name).material = mat.name
  3076. class VIEW3D_MT_gpencil_copy_layer(Menu):
  3077. bl_label = "Copy Layer to Object"
  3078. def draw(self, context):
  3079. layout = self.layout
  3080. view_layer = context.view_layer
  3081. obact = context.active_object
  3082. gpl = context.active_gpencil_layer
  3083. done = False
  3084. if gpl is not None:
  3085. for ob in view_layer.objects:
  3086. if ob.type == 'GPENCIL' and ob != obact:
  3087. layout.operator("gpencil.layer_duplicate_object", text=ob.name).object = ob.name
  3088. done = True
  3089. if done is False:
  3090. layout.label(text="No destination object", icon='ERROR')
  3091. else:
  3092. layout.label(text="No layer to copy", icon='ERROR')
  3093. class VIEW3D_MT_edit_gpencil(Menu):
  3094. bl_label = "Strokes"
  3095. def draw(self, _context):
  3096. layout = self.layout
  3097. layout.menu("VIEW3D_MT_edit_gpencil_transform")
  3098. layout.separator()
  3099. layout.menu("GPENCIL_MT_snap")
  3100. layout.separator()
  3101. layout.menu("VIEW3D_MT_gpencil_animation")
  3102. layout.menu("VIEW3D_MT_edit_gpencil_interpolate")
  3103. layout.separator()
  3104. # Cut, Copy, Paste
  3105. layout.operator("gpencil.duplicate_move", text="Duplicate")
  3106. layout.operator("gpencil.copy", text="Copy", icon='COPYDOWN')
  3107. layout.operator("gpencil.paste", text="Paste", icon='PASTEDOWN').type = 'COPY'
  3108. layout.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE'
  3109. layout.separator()
  3110. layout.operator("gpencil.stroke_smooth", text="Smooth")
  3111. layout.operator("gpencil.stroke_subdivide", text="Subdivide")
  3112. layout.menu("VIEW3D_MT_gpencil_simplify")
  3113. layout.operator("gpencil.stroke_trim", text="Trim")
  3114. layout.separator()
  3115. layout.operator_menu_enum("gpencil.stroke_separate", "mode", text="Separate...")
  3116. layout.operator("gpencil.stroke_split", text="Split")
  3117. layout.operator("gpencil.stroke_merge", text="Merge")
  3118. op = layout.operator("gpencil.stroke_cyclical_set", text="Close")
  3119. op.type = 'CLOSE'
  3120. op.geometry = True
  3121. layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...")
  3122. layout.operator("gpencil.stroke_flip", text="Flip Direction")
  3123. layout.separator()
  3124. layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer")
  3125. layout.menu("VIEW3D_MT_assign_material")
  3126. layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...")
  3127. layout.separator()
  3128. # Convert
  3129. layout.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
  3130. layout.operator_menu_enum("gpencil.stroke_caps_set", text="Toggle Caps...", property="type")
  3131. layout.separator()
  3132. # Remove
  3133. layout.menu("GPENCIL_MT_cleanup")
  3134. layout.menu("VIEW3D_MT_edit_gpencil_delete")
  3135. class VIEW3D_MT_weight_gpencil(Menu):
  3136. bl_label = "Weights"
  3137. def draw(self, _context):
  3138. layout = self.layout
  3139. layout.operator("gpencil.vertex_group_normalize_all", text="Normalize All")
  3140. layout.operator("gpencil.vertex_group_normalize", text="Normalize")
  3141. layout.separator()
  3142. layout.operator("gpencil.vertex_group_invert", text="Invert")
  3143. layout.operator("gpencil.vertex_group_smooth", text="Smooth")
  3144. layout.separator()
  3145. layout.menu("VIEW3D_MT_gpencil_autoweights")
  3146. class VIEW3D_MT_gpencil_animation(Menu):
  3147. bl_label = "Animation"
  3148. @classmethod
  3149. def poll(cls, context):
  3150. ob = context.active_object
  3151. return ob and ob.type == 'GPENCIL' and ob.mode != 'OBJECT'
  3152. def draw(self, _context):
  3153. layout = self.layout
  3154. layout.operator("gpencil.blank_frame_add")
  3155. layout.operator("gpencil.active_frames_delete_all", text="Delete Frame(s)")
  3156. layout.separator()
  3157. layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
  3158. layout.operator("gpencil.frame_duplicate", text="Duplicate All Layers").mode = 'ALL'
  3159. class VIEW3D_MT_edit_gpencil_transform(Menu):
  3160. bl_label = "Transform"
  3161. def draw(self, _context):
  3162. layout = self.layout
  3163. layout.operator("transform.translate")
  3164. layout.operator("transform.rotate")
  3165. layout.operator("transform.resize", text="Scale")
  3166. layout.separator()
  3167. layout.operator("transform.bend", text="Bend")
  3168. layout.operator("transform.shear", text="Shear")
  3169. layout.operator("transform.tosphere", text="To Sphere")
  3170. layout.operator("transform.transform", text="Shrink Fatten").mode = 'GPENCIL_SHRINKFATTEN'
  3171. class VIEW3D_MT_edit_gpencil_interpolate(Menu):
  3172. bl_label = "Interpolate"
  3173. def draw(self, _context):
  3174. layout = self.layout
  3175. layout.operator("gpencil.interpolate", text="Interpolate")
  3176. layout.operator("gpencil.interpolate_sequence", text="Sequence")
  3177. class VIEW3D_MT_object_mode_pie(Menu):
  3178. bl_label = "Mode"
  3179. def draw(self, _context):
  3180. layout = self.layout
  3181. pie = layout.menu_pie()
  3182. pie.operator_enum("object.mode_set", "mode")
  3183. class VIEW3D_MT_view_pie(Menu):
  3184. bl_label = "View"
  3185. bl_idname = "VIEW3D_MT_view_pie"
  3186. def draw(self, _context):
  3187. layout = self.layout
  3188. pie = layout.menu_pie()
  3189. pie.operator_enum("view3d.view_axis", "type")
  3190. pie.operator("view3d.view_camera", text="View Camera", icon='CAMERA_DATA')
  3191. pie.operator("view3d.view_selected", text="View Selected", icon='ZOOM_SELECTED')
  3192. class VIEW3D_MT_transform_gizmo_pie(Menu):
  3193. bl_label = "View"
  3194. def draw(self, context):
  3195. layout = self.layout
  3196. pie = layout.menu_pie()
  3197. # 1: Left
  3198. pie.operator("view3d.transform_gizmo_set", text="Move").type = {'TRANSLATE'}
  3199. # 2: Right
  3200. pie.operator("view3d.transform_gizmo_set", text="Rotate").type = {'ROTATE'}
  3201. # 3: Down
  3202. pie.operator("view3d.transform_gizmo_set", text="Scale").type = {'SCALE'}
  3203. # 4: Up
  3204. pie.prop(context.space_data, "show_gizmo", text="Show Gizmos", icon='GIZMO')
  3205. # 5: Up/Left
  3206. pie.operator("view3d.transform_gizmo_set", text="All").type = {'TRANSLATE', 'ROTATE', 'SCALE'}
  3207. class VIEW3D_MT_shading_pie(Menu):
  3208. bl_label = "Shading"
  3209. def draw(self, context):
  3210. layout = self.layout
  3211. pie = layout.menu_pie()
  3212. view = context.space_data
  3213. pie.prop(view.shading, "type", expand=True)
  3214. class VIEW3D_MT_shading_ex_pie(Menu):
  3215. bl_label = "Shading"
  3216. def draw(self, context):
  3217. layout = self.layout
  3218. pie = layout.menu_pie()
  3219. view = context.space_data
  3220. pie.prop_enum(view.shading, "type", value='WIREFRAME')
  3221. pie.prop_enum(view.shading, "type", value='SOLID')
  3222. # Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: T58661.
  3223. if context.pose_object:
  3224. pie.prop(view.overlay, "show_xray_bone", icon='XRAY')
  3225. else:
  3226. xray_active = (
  3227. (context.mode == 'EDIT_MESH') or
  3228. (view.shading.type in {'SOLID', 'WIREFRAME'})
  3229. )
  3230. if xray_active:
  3231. sub = pie
  3232. else:
  3233. sub = pie.row()
  3234. sub.active = False
  3235. sub.prop(
  3236. view.shading,
  3237. "show_xray_wireframe" if (view.shading.type == 'WIREFRAME') else "show_xray",
  3238. text="Toggle X-Ray",
  3239. icon='XRAY',
  3240. )
  3241. pie.prop(view.overlay, "show_overlays", text="Toggle Overlays", icon='OVERLAY')
  3242. pie.prop_enum(view.shading, "type", value='MATERIAL')
  3243. pie.prop_enum(view.shading, "type", value='RENDERED')
  3244. class VIEW3D_MT_pivot_pie(Menu):
  3245. bl_label = "Pivot Point"
  3246. def draw(self, context):
  3247. layout = self.layout
  3248. pie = layout.menu_pie()
  3249. obj = context.active_object
  3250. mode = context.mode
  3251. pie.prop_enum(context.scene.tool_settings, "transform_pivot_point", value='BOUNDING_BOX_CENTER')
  3252. pie.prop_enum(context.scene.tool_settings, "transform_pivot_point", value='CURSOR')
  3253. pie.prop_enum(context.scene.tool_settings, "transform_pivot_point", value='INDIVIDUAL_ORIGINS')
  3254. pie.prop_enum(context.scene.tool_settings, "transform_pivot_point", value='MEDIAN_POINT')
  3255. pie.prop_enum(context.scene.tool_settings, "transform_pivot_point", value='ACTIVE_ELEMENT')
  3256. if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}):
  3257. pie.prop(context.scene.tool_settings, "use_transform_pivot_point_align")
  3258. class VIEW3D_MT_orientations_pie(Menu):
  3259. bl_label = "Orientation"
  3260. def draw(self, context):
  3261. layout = self.layout
  3262. pie = layout.menu_pie()
  3263. scene = context.scene
  3264. pie.prop(scene.transform_orientation_slots[0], "type", expand=True)
  3265. class VIEW3D_MT_snap_pie(Menu):
  3266. bl_label = "Snap"
  3267. def draw(self, _context):
  3268. layout = self.layout
  3269. pie = layout.menu_pie()
  3270. pie.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid", icon='CURSOR')
  3271. pie.operator("view3d.snap_selected_to_grid", text="Selection to Grid", icon='RESTRICT_SELECT_OFF')
  3272. pie.operator("view3d.snap_cursor_to_selected", text="Cursor to Selected", icon='CURSOR')
  3273. pie.operator(
  3274. "view3d.snap_selected_to_cursor",
  3275. text="Selection to Cursor",
  3276. icon='RESTRICT_SELECT_OFF',
  3277. ).use_offset = False
  3278. pie.operator(
  3279. "view3d.snap_selected_to_cursor",
  3280. text="Selection to Cursor (Keep Offset)",
  3281. icon='RESTRICT_SELECT_OFF',
  3282. ).use_offset = True
  3283. pie.operator("view3d.snap_selected_to_active", text="Selection to Active", icon='RESTRICT_SELECT_OFF')
  3284. pie.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR')
  3285. pie.operator("view3d.snap_cursor_to_active", text="Cursor to Active", icon='CURSOR')
  3286. class VIEW3D_MT_proportional_editing_falloff_pie(Menu):
  3287. bl_label = "Proportional Editing Falloff"
  3288. def draw(self, context):
  3289. layout = self.layout
  3290. pie = layout.menu_pie()
  3291. tool_settings = context.scene.tool_settings
  3292. pie.prop(tool_settings, "proportional_edit_falloff", expand=True)
  3293. # ********** Panel **********
  3294. class VIEW3D_PT_active_tool(Panel, ToolActivePanelHelper):
  3295. bl_space_type = 'VIEW_3D'
  3296. bl_region_type = 'UI'
  3297. bl_category = "Tool"
  3298. # See comment below.
  3299. # bl_options = {'HIDE_HEADER'}
  3300. # Don't show in properties editor.
  3301. @classmethod
  3302. def poll(cls, context):
  3303. return context.area.type == 'VIEW_3D'
  3304. # FIXME(campbell): remove this second panel once 'HIDE_HEADER' works with category tabs,
  3305. # Currently pinning allows ordering headerless panels below panels with headers.
  3306. class VIEW3D_PT_active_tool_duplicate(Panel, ToolActivePanelHelper):
  3307. bl_space_type = 'VIEW_3D'
  3308. bl_region_type = 'UI'
  3309. bl_category = "Tool"
  3310. bl_options = {'HIDE_HEADER'}
  3311. # Only show in properties editor.
  3312. @classmethod
  3313. def poll(cls, context):
  3314. return context.area.type != 'VIEW_3D'
  3315. class VIEW3D_PT_view3d_properties(Panel):
  3316. bl_space_type = 'VIEW_3D'
  3317. bl_region_type = 'UI'
  3318. bl_category = "View"
  3319. bl_label = "View"
  3320. def draw(self, context):
  3321. layout = self.layout
  3322. view = context.space_data
  3323. layout.use_property_split = True
  3324. layout.use_property_decorate = False # No animation.
  3325. flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True)
  3326. col = flow.column()
  3327. subcol = col.column()
  3328. subcol.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews)
  3329. subcol.prop(view, "lens", text="Focal Length")
  3330. subcol = col.column(align=True)
  3331. subcol.prop(view, "clip_start", text="Clip Start")
  3332. subcol.prop(view, "clip_end", text="End")
  3333. subcol.separator()
  3334. col = flow.column()
  3335. subcol = col.column()
  3336. subcol.prop(view, "use_local_camera")
  3337. subcol = col.column()
  3338. subcol.enabled = view.use_local_camera
  3339. subcol.prop(view, "camera", text="Local Camera")
  3340. subcol = col.column(align=True)
  3341. subcol.prop(view, "use_render_border")
  3342. subcol.active = view.region_3d.view_perspective != 'CAMERA'
  3343. class VIEW3D_PT_view3d_lock(Panel):
  3344. bl_space_type = 'VIEW_3D'
  3345. bl_region_type = 'UI'
  3346. bl_category = "View"
  3347. bl_label = "View Lock"
  3348. bl_parent_id = "VIEW3D_PT_view3d_properties"
  3349. def draw(self, context):
  3350. layout = self.layout
  3351. layout.use_property_split = True
  3352. layout.use_property_decorate = False # No animation.
  3353. view = context.space_data
  3354. col = layout.column(align=True)
  3355. subcol = col.column()
  3356. subcol.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews)
  3357. subcol.prop(view, "lock_object")
  3358. lock_object = view.lock_object
  3359. if lock_object:
  3360. if lock_object.type == 'ARMATURE':
  3361. subcol.prop_search(
  3362. view, "lock_bone", lock_object.data,
  3363. "edit_bones" if lock_object.mode == 'EDIT'
  3364. else "bones",
  3365. text="",
  3366. )
  3367. else:
  3368. subcol.prop(view, "lock_cursor", text="Lock to 3D Cursor")
  3369. col.prop(view, "lock_camera")
  3370. class VIEW3D_PT_view3d_cursor(Panel):
  3371. bl_space_type = 'VIEW_3D'
  3372. bl_region_type = 'UI'
  3373. bl_category = "View"
  3374. bl_label = "3D Cursor"
  3375. def draw(self, context):
  3376. layout = self.layout
  3377. cursor = context.scene.cursor
  3378. layout.column().prop(cursor, "location", text="Location")
  3379. rotation_mode = cursor.rotation_mode
  3380. if rotation_mode == 'QUATERNION':
  3381. layout.column().prop(cursor, "rotation_quaternion", text="Rotation")
  3382. elif rotation_mode == 'AXIS_ANGLE':
  3383. layout.column().prop(cursor, "rotation_axis_angle", text="Rotation")
  3384. else:
  3385. layout.column().prop(cursor, "rotation_euler", text="Rotation")
  3386. layout.prop(cursor, "rotation_mode", text="")
  3387. class VIEW3D_PT_collections(Panel):
  3388. bl_space_type = 'VIEW_3D'
  3389. bl_region_type = 'UI'
  3390. bl_category = "View"
  3391. bl_label = "Collections"
  3392. bl_options = {'DEFAULT_CLOSED'}
  3393. def _draw_collection(self, layout, view_layer, collection, index):
  3394. need_separator = index
  3395. for child in collection.children:
  3396. index += 1
  3397. if child.exclude:
  3398. continue
  3399. if child.collection.hide_viewport:
  3400. continue
  3401. if need_separator:
  3402. layout.separator()
  3403. need_separator = False
  3404. icon = 'BLANK1'
  3405. # has_objects = True
  3406. if child.has_selected_objects(view_layer):
  3407. icon = 'LAYER_ACTIVE'
  3408. elif child.has_objects():
  3409. icon = 'LAYER_USED'
  3410. else:
  3411. # has_objects = False
  3412. pass
  3413. row = layout.row()
  3414. sub = row.split(factor=0.98)
  3415. subrow = sub.row()
  3416. subrow.alignment = 'LEFT'
  3417. subrow.operator(
  3418. "object.hide_collection", text=child.name, icon=icon, emboss=False,
  3419. ).collection_index = index
  3420. sub = row.split()
  3421. subrow = sub.row(align=True)
  3422. subrow.alignment = 'RIGHT'
  3423. subrow.active = collection.is_visible # Parent collection runtime visibility
  3424. subrow.prop(child, "hide_viewport", text="", emboss=False)
  3425. for child in collection.children:
  3426. index = self._draw_collection(layout, view_layer, child, index)
  3427. return index
  3428. def draw(self, context):
  3429. layout = self.layout
  3430. layout.use_property_split = False
  3431. view_layer = context.view_layer
  3432. # We pass index 0 here beause the index is increased
  3433. # so the first real index is 1
  3434. # And we start with index as 1 because we skip the master collection
  3435. self._draw_collection(layout, view_layer, view_layer.layer_collection, 0)
  3436. class VIEW3D_PT_object_type_visibility(Panel):
  3437. bl_space_type = 'VIEW_3D'
  3438. bl_region_type = 'HEADER'
  3439. bl_label = "View Object Types"
  3440. bl_ui_units_x = 6
  3441. def draw(self, context):
  3442. layout = self.layout
  3443. layout.use_property_split = True
  3444. view = context.space_data
  3445. layout.label(text="Object Types Visibility")
  3446. col = layout.column()
  3447. attr_object_types = (
  3448. # Geometry
  3449. ("mesh", "Mesh"),
  3450. ("curve", "Curve"),
  3451. ("surf", "Surface"),
  3452. ("meta", "Meta"),
  3453. ("font", "Text"),
  3454. ("grease_pencil", "Grease Pencil"),
  3455. (None, None),
  3456. # Other
  3457. ("armature", "Armature"),
  3458. ("lattice", "Lattice"),
  3459. ("empty", "Empty"),
  3460. ("light", "Light"),
  3461. ("light_probe", "Light Probe"),
  3462. ("camera", "Camera"),
  3463. ("speaker", "Speaker"),
  3464. )
  3465. for attr, attr_name in attr_object_types:
  3466. if attr is None:
  3467. col.separator()
  3468. continue
  3469. attr_v = "show_object_viewport_" f"{attr:s}"
  3470. attr_s = "show_object_select_" f"{attr:s}"
  3471. icon_v = 'HIDE_OFF' if getattr(view, attr_v) else 'HIDE_ON'
  3472. icon_s = 'RESTRICT_SELECT_OFF' if getattr(view, attr_s) else 'RESTRICT_SELECT_ON'
  3473. row = col.row(align=True)
  3474. row.alignment = 'RIGHT'
  3475. row.label(text=attr_name)
  3476. row.prop(view, attr_v, text="", icon=icon_v, emboss=False)
  3477. rowsub = row.row(align=True)
  3478. rowsub.active = getattr(view, attr_v)
  3479. rowsub.prop(view, attr_s, text="", icon=icon_s, emboss=False)
  3480. class VIEW3D_PT_shading(Panel):
  3481. bl_space_type = 'VIEW_3D'
  3482. bl_region_type = 'HEADER'
  3483. bl_label = "Shading"
  3484. bl_ui_units_x = 12
  3485. @classmethod
  3486. def get_shading(cls, context):
  3487. # Get settings from 3D viewport or OpenGL render engine
  3488. view = context.space_data
  3489. if view.type == 'VIEW_3D':
  3490. return view.shading
  3491. else:
  3492. return context.scene.display.shading
  3493. def draw(self, _context):
  3494. layout = self.layout
  3495. layout.label(text="Viewport Shading")
  3496. class VIEW3D_PT_shading_lighting(Panel):
  3497. bl_space_type = 'VIEW_3D'
  3498. bl_region_type = 'HEADER'
  3499. bl_label = "Lighting"
  3500. bl_parent_id = 'VIEW3D_PT_shading'
  3501. @classmethod
  3502. def poll(cls, context):
  3503. shading = VIEW3D_PT_shading.get_shading(context)
  3504. return shading.type in {'SOLID', 'MATERIAL'}
  3505. def draw(self, context):
  3506. layout = self.layout
  3507. shading = VIEW3D_PT_shading.get_shading(context)
  3508. col = layout.column()
  3509. split = col.split(factor=0.9)
  3510. if shading.type == 'SOLID':
  3511. split.row().prop(shading, "light", expand=True)
  3512. col = split.column()
  3513. split = layout.split(factor=0.9)
  3514. col = split.column()
  3515. sub = col.row()
  3516. if shading.light == 'STUDIO':
  3517. prefs = context.preferences
  3518. system = prefs.system
  3519. if not system.use_studio_light_edit:
  3520. sub.scale_y = 0.6 # smaller studiolight preview
  3521. sub.template_icon_view(shading, "studio_light", scale_popup=3.0)
  3522. else:
  3523. sub.prop(
  3524. system,
  3525. "use_studio_light_edit",
  3526. text="Disable Studio Light Edit",
  3527. icon='NONE',
  3528. toggle=True,
  3529. )
  3530. col = split.column()
  3531. col.operator("preferences.studiolight_show", emboss=False, text="", icon='PREFERENCES')
  3532. split = layout.split(factor=0.9)
  3533. col = split.column()
  3534. row = col.row()
  3535. row.prop(shading, "use_world_space_lighting", text="", icon='WORLD', toggle=True)
  3536. row = row.row()
  3537. row.active = shading.use_world_space_lighting
  3538. row.prop(shading, "studiolight_rotate_z", text="Rotation")
  3539. col = split.column() # to align properly with above
  3540. elif shading.light == 'MATCAP':
  3541. sub.scale_y = 0.6 # smaller matcap preview
  3542. sub.template_icon_view(shading, "studio_light", scale_popup=3.0)
  3543. col = split.column()
  3544. col.operator("preferences.studiolight_show", emboss=False, text="", icon='PREFERENCES')
  3545. col.operator("view3d.toggle_matcap_flip", emboss=False, text="", icon='ARROW_LEFTRIGHT')
  3546. elif shading.type == 'MATERIAL':
  3547. col.prop(shading, "use_scene_lights")
  3548. col.prop(shading, "use_scene_world")
  3549. if not shading.use_scene_world:
  3550. col = layout.column()
  3551. split = col.split(factor=0.9)
  3552. col = split.column()
  3553. sub = col.row()
  3554. sub.scale_y = 0.6
  3555. sub.template_icon_view(shading, "studio_light", scale_popup=3)
  3556. col = split.column()
  3557. col.operator("preferences.studiolight_show", emboss=False, text="", icon='PREFERENCES')
  3558. if shading.selected_studio_light.type == 'WORLD':
  3559. split = layout.split(factor=0.9)
  3560. col = split.column()
  3561. col.prop(shading, "studiolight_rotate_z", text="Rotation")
  3562. col.prop(shading, "studiolight_background_alpha")
  3563. col = split.column() # to align properly with above
  3564. class VIEW3D_PT_shading_color(Panel):
  3565. bl_space_type = 'VIEW_3D'
  3566. bl_region_type = 'HEADER'
  3567. bl_label = "Color"
  3568. bl_parent_id = 'VIEW3D_PT_shading'
  3569. @classmethod
  3570. def poll(cls, context):
  3571. shading = VIEW3D_PT_shading.get_shading(context)
  3572. return shading.type in {'WIREFRAME', 'SOLID'}
  3573. def _draw_color_type(self, context):
  3574. layout = self.layout
  3575. shading = VIEW3D_PT_shading.get_shading(context)
  3576. layout.grid_flow(columns=3, align=True).prop(shading, "color_type", expand=True)
  3577. if shading.color_type == 'SINGLE':
  3578. layout.row().prop(shading, "single_color", text="")
  3579. def _draw_background_color(self, context):
  3580. layout = self.layout
  3581. shading = VIEW3D_PT_shading.get_shading(context)
  3582. layout.row().label(text="Background")
  3583. layout.row().prop(shading, "background_type", expand=True)
  3584. if shading.background_type == 'VIEWPORT':
  3585. layout.row().prop(shading, "background_color", text="")
  3586. def draw(self, context):
  3587. shading = VIEW3D_PT_shading.get_shading(context)
  3588. if shading.type == 'WIREFRAME':
  3589. self.layout.row().prop(shading, "wireframe_color_type", expand=True)
  3590. else:
  3591. self._draw_color_type(context)
  3592. self.layout.separator()
  3593. self._draw_background_color(context)
  3594. class VIEW3D_PT_shading_options(Panel):
  3595. bl_space_type = 'VIEW_3D'
  3596. bl_region_type = 'HEADER'
  3597. bl_label = "Options"
  3598. bl_parent_id = 'VIEW3D_PT_shading'
  3599. @classmethod
  3600. def poll(cls, context):
  3601. shading = VIEW3D_PT_shading.get_shading(context)
  3602. return shading.type in {'WIREFRAME', 'SOLID'}
  3603. def draw(self, context):
  3604. layout = self.layout
  3605. shading = VIEW3D_PT_shading.get_shading(context)
  3606. col = layout.column()
  3607. if shading.type == 'SOLID':
  3608. col.prop(shading, "show_backface_culling")
  3609. row = col.row(align=True)
  3610. if shading.type == 'WIREFRAME':
  3611. row.prop(shading, "show_xray_wireframe", text="")
  3612. sub = row.row()
  3613. sub.active = shading.show_xray_wireframe
  3614. sub.prop(shading, "xray_alpha_wireframe", text="X-Ray")
  3615. elif shading.type == 'SOLID':
  3616. row.prop(shading, "show_xray", text="")
  3617. sub = row.row()
  3618. sub.active = shading.show_xray
  3619. sub.prop(shading, "xray_alpha", text="X-Ray")
  3620. # X-ray mode is off when alpha is 1.0
  3621. xray_active = shading.show_xray and shading.xray_alpha != 1
  3622. row = col.row(align=True)
  3623. row.prop(shading, "show_shadows", text="")
  3624. row.active = not xray_active
  3625. sub = row.row(align=True)
  3626. sub.active = shading.show_shadows
  3627. sub.prop(shading, "shadow_intensity", text="Shadow")
  3628. sub.popover(
  3629. panel="VIEW3D_PT_shading_options_shadow",
  3630. icon='PREFERENCES',
  3631. text="",
  3632. )
  3633. col = layout.column()
  3634. row = col.row()
  3635. row.active = not xray_active
  3636. row.prop(shading, "show_cavity")
  3637. if shading.show_cavity and not xray_active:
  3638. row.prop(shading, "cavity_type", text="Type")
  3639. if shading.cavity_type in {'WORLD', 'BOTH'}:
  3640. col.label(text="World Space")
  3641. sub = col.row(align=True)
  3642. sub.prop(shading, "cavity_ridge_factor", text="Ridge")
  3643. sub.prop(shading, "cavity_valley_factor", text="Valley")
  3644. sub.popover(
  3645. panel="VIEW3D_PT_shading_options_ssao",
  3646. icon='PREFERENCES',
  3647. text="",
  3648. )
  3649. if shading.cavity_type in {'SCREEN', 'BOTH'}:
  3650. col.label(text="Screen Space")
  3651. sub = col.row(align=True)
  3652. sub.prop(shading, "curvature_ridge_factor", text="Ridge")
  3653. sub.prop(shading, "curvature_valley_factor", text="Valley")
  3654. row = col.row()
  3655. row.active = not xray_active
  3656. row.prop(shading, "use_dof", text="Depth Of Field")
  3657. if shading.type in {'WIREFRAME', 'SOLID'}:
  3658. row = layout.split()
  3659. row.prop(shading, "show_object_outline")
  3660. sub = row.row()
  3661. sub.active = shading.show_object_outline
  3662. sub.prop(shading, "object_outline_color", text="")
  3663. col = layout.column()
  3664. if (shading.light == 'STUDIO') and (shading.type != 'WIREFRAME'):
  3665. col.prop(shading, "show_specular_highlight", text="Specular Lighting")
  3666. class VIEW3D_PT_shading_options_shadow(Panel):
  3667. bl_label = "Shadow Settings"
  3668. bl_space_type = 'VIEW_3D'
  3669. bl_region_type = 'HEADER'
  3670. def draw(self, context):
  3671. layout = self.layout
  3672. layout.use_property_split = True
  3673. scene = context.scene
  3674. col = layout.column()
  3675. col.prop(scene.display, "light_direction")
  3676. col.prop(scene.display, "shadow_shift")
  3677. col.prop(scene.display, "shadow_focus")
  3678. class VIEW3D_PT_shading_options_ssao(Panel):
  3679. bl_label = "SSAO Settings"
  3680. bl_space_type = 'VIEW_3D'
  3681. bl_region_type = 'HEADER'
  3682. def draw(self, context):
  3683. layout = self.layout
  3684. layout.use_property_split = True
  3685. scene = context.scene
  3686. col = layout.column(align=True)
  3687. col.prop(scene.display, "matcap_ssao_samples")
  3688. col.prop(scene.display, "matcap_ssao_distance")
  3689. col.prop(scene.display, "matcap_ssao_attenuation")
  3690. class VIEW3D_PT_gizmo_display(Panel):
  3691. bl_space_type = 'VIEW_3D'
  3692. bl_region_type = 'HEADER'
  3693. bl_label = "Gizmo"
  3694. def draw(self, context):
  3695. layout = self.layout
  3696. scene = context.scene
  3697. view = context.space_data
  3698. col = layout.column()
  3699. col.label(text="Viewport Gizmos")
  3700. col.active = view.show_gizmo
  3701. colsub = col.column()
  3702. colsub.prop(view, "show_gizmo_navigate", text="Navigate")
  3703. colsub.prop(view, "show_gizmo_tool", text="Active Tools")
  3704. colsub.prop(view, "show_gizmo_context", text="Active Object")
  3705. layout.separator()
  3706. col = layout.column()
  3707. col.active = view.show_gizmo_context
  3708. col.label(text="Object Gizmos")
  3709. col.prop(scene.transform_orientation_slots[1], "type", text="")
  3710. col.prop(view, "show_gizmo_object_translate", text="Move")
  3711. col.prop(view, "show_gizmo_object_rotate", text="Rotate")
  3712. col.prop(view, "show_gizmo_object_scale", text="Scale")
  3713. layout.separator()
  3714. # Match order of object type visibility
  3715. col = layout.column()
  3716. col.label(text="Empty")
  3717. col.prop(view, "show_gizmo_empty_image", text="Image")
  3718. col.prop(view, "show_gizmo_empty_force_field", text="Force Field")
  3719. col.label(text="Light")
  3720. col.prop(view, "show_gizmo_light_size", text="Size")
  3721. col.prop(view, "show_gizmo_light_look_at", text="Look At")
  3722. col.label(text="Camera")
  3723. col.prop(view, "show_gizmo_camera_lens", text="Lens")
  3724. col.prop(view, "show_gizmo_camera_dof_distance", text="Focus Distance")
  3725. class VIEW3D_PT_overlay(Panel):
  3726. bl_space_type = 'VIEW_3D'
  3727. bl_region_type = 'HEADER'
  3728. bl_label = "Overlays"
  3729. bl_ui_units_x = 13
  3730. def draw(self, _context):
  3731. layout = self.layout
  3732. layout.label(text="Viewport Overlays")
  3733. class VIEW3D_PT_overlay_guides(Panel):
  3734. bl_space_type = 'VIEW_3D'
  3735. bl_region_type = 'HEADER'
  3736. bl_parent_id = 'VIEW3D_PT_overlay'
  3737. bl_label = "Guides"
  3738. def draw(self, context):
  3739. layout = self.layout
  3740. view = context.space_data
  3741. overlay = view.overlay
  3742. shading = view.shading
  3743. display_all = overlay.show_overlays
  3744. col = layout.column()
  3745. col.active = display_all
  3746. split = col.split()
  3747. sub = split.column()
  3748. row = sub.row()
  3749. row_el = row.column()
  3750. row_el.prop(overlay, "show_ortho_grid", text="Grid")
  3751. grid_active = (
  3752. view.region_quadviews or
  3753. (view.region_3d.is_orthographic_side_view and not view.region_3d.is_perspective)
  3754. )
  3755. row_el.active = grid_active
  3756. row.prop(overlay, "show_floor", text="Floor")
  3757. if overlay.show_floor or overlay.show_ortho_grid:
  3758. sub = col.row(align=True)
  3759. sub.active = (
  3760. (overlay.show_floor and not view.region_3d.is_orthographic_side_view) or
  3761. (overlay.show_ortho_grid and grid_active)
  3762. )
  3763. sub.prop(overlay, "grid_scale", text="Scale")
  3764. sub.prop(overlay, "grid_subdivisions", text="Subdivisions")
  3765. sub = split.column()
  3766. row = sub.row()
  3767. row.label(text="Axes")
  3768. subrow = row.row(align=True)
  3769. subrow.prop(overlay, "show_axis_x", text="X", toggle=True)
  3770. subrow.prop(overlay, "show_axis_y", text="Y", toggle=True)
  3771. subrow.prop(overlay, "show_axis_z", text="Z", toggle=True)
  3772. split = col.split()
  3773. sub = split.column()
  3774. sub.prop(overlay, "show_text", text="Text Info")
  3775. sub = split.column()
  3776. sub.prop(overlay, "show_cursor", text="3D Cursor")
  3777. if shading.type == 'MATERIAL':
  3778. col.prop(overlay, "show_look_dev")
  3779. col.prop(overlay, "show_annotation", text="Annotations")
  3780. class VIEW3D_PT_overlay_object(Panel):
  3781. bl_space_type = 'VIEW_3D'
  3782. bl_region_type = 'HEADER'
  3783. bl_parent_id = 'VIEW3D_PT_overlay'
  3784. bl_label = "Objects"
  3785. def draw(self, context):
  3786. layout = self.layout
  3787. view = context.space_data
  3788. overlay = view.overlay
  3789. display_all = overlay.show_overlays
  3790. col = layout.column(align=True)
  3791. col.active = display_all
  3792. split = col.split()
  3793. sub = split.column(align=True)
  3794. sub.prop(overlay, "show_extras", text="Extras")
  3795. sub.prop(overlay, "show_relationship_lines")
  3796. sub.prop(overlay, "show_outline_selected")
  3797. sub = split.column(align=True)
  3798. sub.prop(overlay, "show_bones", text="Bones")
  3799. sub.prop(overlay, "show_motion_paths")
  3800. sub.prop(overlay, "show_object_origins", text="Origins")
  3801. subsub = sub.column()
  3802. subsub.active = overlay.show_object_origins
  3803. subsub.prop(overlay, "show_object_origins_all", text="Origins (All)")
  3804. class VIEW3D_PT_overlay_geometry(Panel):
  3805. bl_space_type = 'VIEW_3D'
  3806. bl_region_type = 'HEADER'
  3807. bl_parent_id = 'VIEW3D_PT_overlay'
  3808. bl_label = "Geometry"
  3809. def draw(self, context):
  3810. layout = self.layout
  3811. view = context.space_data
  3812. overlay = view.overlay
  3813. display_all = overlay.show_overlays
  3814. is_wireframes = view.shading.type == 'WIREFRAME'
  3815. col = layout.column()
  3816. col.active = display_all
  3817. row = col.row(align=True)
  3818. if not is_wireframes:
  3819. row.prop(overlay, "show_wireframes", text="")
  3820. sub = row.row()
  3821. sub.active = overlay.show_wireframes or is_wireframes
  3822. sub.prop(overlay, "wireframe_threshold", text="Wireframe")
  3823. col = layout.column(align=True)
  3824. col.active = display_all
  3825. col.prop(overlay, "show_face_orientation")
  3826. # sub.prop(overlay, "show_onion_skins")
  3827. class VIEW3D_PT_overlay_motion_tracking(Panel):
  3828. bl_space_type = 'VIEW_3D'
  3829. bl_region_type = 'HEADER'
  3830. bl_parent_id = 'VIEW3D_PT_overlay'
  3831. bl_label = "Motion Tracking"
  3832. def draw_header(self, context):
  3833. view = context.space_data
  3834. self.layout.prop(view, "show_reconstruction", text="")
  3835. def draw(self, context):
  3836. layout = self.layout
  3837. view = context.space_data
  3838. overlay = view.overlay
  3839. display_all = overlay.show_overlays
  3840. col = layout.column()
  3841. col.active = display_all
  3842. if view.show_reconstruction:
  3843. split = col.split()
  3844. sub = split.column(align=True)
  3845. sub.active = view.show_reconstruction
  3846. sub.prop(view, "show_camera_path", text="Camera Path")
  3847. sub = split.column()
  3848. sub.prop(view, "show_bundle_names", text="Marker Names")
  3849. col = layout.column()
  3850. col.label(text="Tracks:")
  3851. row = col.row(align=True)
  3852. row.prop(view, "tracks_display_type", text="")
  3853. row.prop(view, "tracks_display_size", text="Size")
  3854. class VIEW3D_PT_overlay_edit_mesh(Panel):
  3855. bl_space_type = 'VIEW_3D'
  3856. bl_region_type = 'HEADER'
  3857. bl_parent_id = 'VIEW3D_PT_overlay'
  3858. bl_label = "Mesh Edit Mode"
  3859. @classmethod
  3860. def poll(cls, context):
  3861. return context.mode == 'EDIT_MESH'
  3862. def draw(self, context):
  3863. layout = self.layout
  3864. view = context.space_data
  3865. overlay = view.overlay
  3866. display_all = overlay.show_overlays
  3867. col = layout.column()
  3868. col.active = display_all
  3869. split = col.split()
  3870. sub = split.column()
  3871. sub.prop(overlay, "show_edges", text="Edges")
  3872. sub = split.column()
  3873. sub.prop(overlay, "show_faces", text="Faces")
  3874. sub = split.column()
  3875. sub.prop(overlay, "show_face_center", text="Center")
  3876. row = col.row(align=True)
  3877. row.prop(overlay, "show_edge_crease", text="Creases", toggle=True)
  3878. row.prop(overlay, "show_edge_sharp", text="Sharp", text_ctxt=i18n_contexts.plural, toggle=True)
  3879. row.prop(overlay, "show_edge_bevel_weight", text="Bevel", toggle=True)
  3880. row.prop(overlay, "show_edge_seams", text="Seams", toggle=True)
  3881. if context.preferences.view.show_developer_ui:
  3882. col.label(text="Developer")
  3883. col.prop(overlay, "show_extra_indices", text="Indices")
  3884. class VIEW3D_PT_overlay_edit_mesh_shading(Panel):
  3885. bl_space_type = 'VIEW_3D'
  3886. bl_region_type = 'HEADER'
  3887. bl_parent_id = 'VIEW3D_PT_overlay_edit_mesh'
  3888. bl_label = "Shading"
  3889. @classmethod
  3890. def poll(cls, context):
  3891. return context.mode == 'EDIT_MESH'
  3892. def draw(self, context):
  3893. layout = self.layout
  3894. view = context.space_data
  3895. shading = view.shading
  3896. overlay = view.overlay
  3897. tool_settings = context.tool_settings
  3898. display_all = overlay.show_overlays
  3899. statvis = tool_settings.statvis
  3900. col = layout.column()
  3901. col.active = display_all
  3902. col.prop(overlay, "show_occlude_wire")
  3903. col.prop(overlay, "show_weight", text="Vertex Group Weights")
  3904. if overlay.show_weight:
  3905. row = col.split(factor=0.33)
  3906. row.label(text="Zero Weights")
  3907. sub = row.row()
  3908. sub.prop(tool_settings, "vertex_group_user", expand=True)
  3909. if shading.type == 'WIREFRAME':
  3910. xray = shading.show_xray_wireframe and shading.xray_alpha_wireframe < 1.0
  3911. elif shading.type == 'SOLID':
  3912. xray = shading.show_xray and shading.xray_alpha < 1.0
  3913. else:
  3914. xray = False
  3915. statvis_active = not xray
  3916. row = col.row()
  3917. row.active = statvis_active
  3918. row.prop(overlay, "show_statvis", text="Mesh Analysis")
  3919. if overlay.show_statvis:
  3920. col = col.column()
  3921. col.active = statvis_active
  3922. sub = col.split()
  3923. sub.label(text="Type")
  3924. sub.prop(statvis, "type", text="")
  3925. statvis_type = statvis.type
  3926. if statvis_type == 'OVERHANG':
  3927. row = col.row(align=True)
  3928. row.prop(statvis, "overhang_min", text="Minimum")
  3929. row.prop(statvis, "overhang_max", text="Maximum")
  3930. col.row().prop(statvis, "overhang_axis", expand=True)
  3931. elif statvis_type == 'THICKNESS':
  3932. row = col.row(align=True)
  3933. row.prop(statvis, "thickness_min", text="Minimum")
  3934. row.prop(statvis, "thickness_max", text="Maximum")
  3935. col.prop(statvis, "thickness_samples")
  3936. elif statvis_type == 'INTERSECT':
  3937. pass
  3938. elif statvis_type == 'DISTORT':
  3939. row = col.row(align=True)
  3940. row.prop(statvis, "distort_min", text="Minimum")
  3941. row.prop(statvis, "distort_max", text="Maximum")
  3942. elif statvis_type == 'SHARP':
  3943. row = col.row(align=True)
  3944. row.prop(statvis, "sharp_min", text="Minimum")
  3945. row.prop(statvis, "sharp_max", text="Maximum")
  3946. class VIEW3D_PT_overlay_edit_mesh_measurement(Panel):
  3947. bl_space_type = 'VIEW_3D'
  3948. bl_region_type = 'HEADER'
  3949. bl_parent_id = 'VIEW3D_PT_overlay_edit_mesh'
  3950. bl_label = "Measurement"
  3951. @classmethod
  3952. def poll(cls, context):
  3953. return context.mode == 'EDIT_MESH'
  3954. def draw(self, context):
  3955. layout = self.layout
  3956. view = context.space_data
  3957. overlay = view.overlay
  3958. display_all = overlay.show_overlays
  3959. col = layout.column()
  3960. col.active = display_all
  3961. split = col.split()
  3962. sub = split.column()
  3963. sub.prop(overlay, "show_extra_edge_length", text="Edge Length")
  3964. sub.prop(overlay, "show_extra_edge_angle", text="Edge Angle")
  3965. sub = split.column()
  3966. sub.prop(overlay, "show_extra_face_area", text="Face Area")
  3967. sub.prop(overlay, "show_extra_face_angle", text="Face Angle")
  3968. class VIEW3D_PT_overlay_edit_mesh_normals(Panel):
  3969. bl_space_type = 'VIEW_3D'
  3970. bl_region_type = 'HEADER'
  3971. bl_parent_id = 'VIEW3D_PT_overlay_edit_mesh'
  3972. bl_label = "Normals"
  3973. @classmethod
  3974. def poll(cls, context):
  3975. return context.mode == 'EDIT_MESH'
  3976. def draw(self, context):
  3977. layout = self.layout
  3978. view = context.space_data
  3979. overlay = view.overlay
  3980. display_all = overlay.show_overlays
  3981. col = layout.column()
  3982. col.active = display_all
  3983. row = col.row(align=True)
  3984. row.prop(overlay, "show_vertex_normals", text="", icon='NORMALS_VERTEX')
  3985. row.prop(overlay, "show_split_normals", text="", icon='NORMALS_VERTEX_FACE')
  3986. row.prop(overlay, "show_face_normals", text="", icon='NORMALS_FACE')
  3987. sub = row.row(align=True)
  3988. sub.active = overlay.show_vertex_normals or overlay.show_face_normals or overlay.show_split_normals
  3989. sub.prop(overlay, "normals_length", text="Size")
  3990. class VIEW3D_PT_overlay_edit_mesh_freestyle(Panel):
  3991. bl_space_type = 'VIEW_3D'
  3992. bl_region_type = 'HEADER'
  3993. bl_parent_id = 'VIEW3D_PT_overlay'
  3994. bl_label = "Freestyle"
  3995. @classmethod
  3996. def poll(cls, context):
  3997. return context.mode == 'EDIT_MESH' and bpy.app.build_options.freestyle
  3998. def draw(self, context):
  3999. layout = self.layout
  4000. view = context.space_data
  4001. overlay = view.overlay
  4002. display_all = overlay.show_overlays
  4003. col = layout.column()
  4004. col.active = display_all
  4005. row = col.row()
  4006. row.prop(overlay, "show_freestyle_edge_marks", text="Edge Marks")
  4007. row.prop(overlay, "show_freestyle_face_marks", text="Face Marks")
  4008. class VIEW3D_PT_overlay_edit_curve(Panel):
  4009. bl_space_type = 'VIEW_3D'
  4010. bl_region_type = 'HEADER'
  4011. bl_parent_id = 'VIEW3D_PT_overlay'
  4012. bl_label = "Curve Edit Mode"
  4013. @classmethod
  4014. def poll(cls, context):
  4015. return context.mode == 'EDIT_CURVE'
  4016. def draw(self, context):
  4017. layout = self.layout
  4018. view = context.space_data
  4019. overlay = view.overlay
  4020. display_all = overlay.show_overlays
  4021. col = layout.column()
  4022. col.active = display_all
  4023. row = col.row()
  4024. row.prop(overlay, "show_curve_handles", text="Handles")
  4025. row = col.row()
  4026. row.prop(overlay, "show_curve_normals", text="")
  4027. sub = row.row()
  4028. sub.active = overlay.show_curve_normals
  4029. sub.prop(overlay, "normals_length", text="Normals")
  4030. class VIEW3D_PT_overlay_sculpt(Panel):
  4031. bl_space_type = 'VIEW_3D'
  4032. bl_context = ".sculpt_mode"
  4033. bl_region_type = 'HEADER'
  4034. bl_parent_id = 'VIEW3D_PT_overlay'
  4035. bl_label = "Sculpt"
  4036. @classmethod
  4037. def poll(cls, context):
  4038. return (
  4039. context.mode == 'SCULPT' and
  4040. (context.sculpt_object and context.tool_settings.sculpt)
  4041. )
  4042. def draw(self, context):
  4043. layout = self.layout
  4044. tool_settings = context.tool_settings
  4045. sculpt = tool_settings.sculpt
  4046. view = context.space_data
  4047. overlay = view.overlay
  4048. layout.prop(sculpt, "show_diffuse_color")
  4049. row = layout.row(align=True)
  4050. row.prop(sculpt, "show_mask", text="")
  4051. sub = row.row()
  4052. sub.active = sculpt.show_mask
  4053. sub.prop(overlay, "sculpt_mode_mask_opacity", text="Mask")
  4054. class VIEW3D_PT_overlay_pose(Panel):
  4055. bl_space_type = 'VIEW_3D'
  4056. bl_region_type = 'HEADER'
  4057. bl_parent_id = 'VIEW3D_PT_overlay'
  4058. bl_label = "Pose Mode"
  4059. @classmethod
  4060. def poll(cls, context):
  4061. mode = context.mode
  4062. return (
  4063. (mode == 'POSE') or
  4064. (mode == 'PAINT_WEIGHT' and context.pose_object)
  4065. )
  4066. def draw(self, context):
  4067. layout = self.layout
  4068. view = context.space_data
  4069. mode = context.mode
  4070. overlay = view.overlay
  4071. display_all = overlay.show_overlays
  4072. col = layout.column()
  4073. col.active = display_all
  4074. if mode == 'POSE':
  4075. row = col.row()
  4076. row.prop(overlay, "show_xray_bone", text="")
  4077. sub = row.row()
  4078. sub.active = display_all and overlay.show_xray_bone
  4079. sub.prop(overlay, "xray_alpha_bone", text="Fade Geometry")
  4080. else:
  4081. row = col.row()
  4082. row.prop(overlay, "show_xray_bone")
  4083. class VIEW3D_PT_overlay_paint(Panel):
  4084. bl_space_type = 'VIEW_3D'
  4085. bl_region_type = 'HEADER'
  4086. bl_parent_id = 'VIEW3D_PT_overlay'
  4087. bl_label = ""
  4088. @classmethod
  4089. def poll(cls, context):
  4090. return context.mode in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}
  4091. def draw_header(self, context):
  4092. layout = self.layout
  4093. layout.label(text={
  4094. 'PAINT_TEXTURE': "Texture Paint",
  4095. 'PAINT_VERTEX': "Vertex Paint",
  4096. 'PAINT_WEIGHT': "Weight Paint",
  4097. }[context.mode])
  4098. def draw(self, context):
  4099. layout = self.layout
  4100. view = context.space_data
  4101. overlay = view.overlay
  4102. display_all = overlay.show_overlays
  4103. col = layout.column()
  4104. col.active = display_all
  4105. col.prop(overlay, {
  4106. 'PAINT_TEXTURE': "texture_paint_mode_opacity",
  4107. 'PAINT_VERTEX': "vertex_paint_mode_opacity",
  4108. 'PAINT_WEIGHT': "weight_paint_mode_opacity",
  4109. }[context.mode], text="Opacity")
  4110. if context.mode == 'PAINT_WEIGHT':
  4111. row = col.split(factor=0.33)
  4112. row.label(text="Zero Weights")
  4113. sub = row.row()
  4114. sub.prop(context.tool_settings, "vertex_group_user", expand=True)
  4115. col.prop(overlay, "show_wpaint_contours")
  4116. if context.mode in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
  4117. col.prop(overlay, "show_paint_wire")
  4118. class VIEW3D_PT_pivot_point(Panel):
  4119. bl_space_type = 'VIEW_3D'
  4120. bl_region_type = 'HEADER'
  4121. bl_label = "Pivot Point"
  4122. bl_ui_units_x = 8
  4123. def draw(self, context):
  4124. tool_settings = context.tool_settings
  4125. obj = context.active_object
  4126. mode = context.mode
  4127. layout = self.layout
  4128. col = layout.column()
  4129. col.label(text="Pivot Point")
  4130. col.prop(tool_settings, "transform_pivot_point", expand=True)
  4131. if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}):
  4132. col.separator()
  4133. col.prop(tool_settings, "use_transform_pivot_point_align")
  4134. class VIEW3D_PT_snapping(Panel):
  4135. bl_space_type = 'VIEW_3D'
  4136. bl_region_type = 'HEADER'
  4137. bl_label = "Snapping"
  4138. def draw(self, context):
  4139. tool_settings = context.tool_settings
  4140. snap_elements = tool_settings.snap_elements
  4141. obj = context.active_object
  4142. object_mode = 'OBJECT' if obj is None else obj.mode
  4143. layout = self.layout
  4144. col = layout.column()
  4145. col.label(text="Snapping")
  4146. col.prop(tool_settings, "snap_elements", expand=True)
  4147. col.separator()
  4148. if 'INCREMENT' in snap_elements:
  4149. col.prop(tool_settings, "use_snap_grid_absolute")
  4150. if snap_elements != {'INCREMENT'}:
  4151. col.label(text="Target")
  4152. row = col.row(align=True)
  4153. row.prop(tool_settings, "snap_target", expand=True)
  4154. if obj:
  4155. if object_mode == 'EDIT':
  4156. col.prop(tool_settings, "use_snap_self")
  4157. if object_mode in {'OBJECT', 'POSE', 'EDIT', 'WEIGHT_PAINT'}:
  4158. col.prop(tool_settings, "use_snap_align_rotation")
  4159. if 'FACE' in snap_elements:
  4160. col.prop(tool_settings, "use_snap_project")
  4161. if 'VOLUME' in snap_elements:
  4162. col.prop(tool_settings, "use_snap_peel_object")
  4163. col.label(text="Affect")
  4164. row = col.row(align=True)
  4165. row.prop(tool_settings, "use_snap_translate", text="Move", toggle=True)
  4166. row.prop(tool_settings, "use_snap_rotate", text="Rotate", toggle=True)
  4167. row.prop(tool_settings, "use_snap_scale", text="Scale", toggle=True)
  4168. class VIEW3D_PT_proportional_edit(Panel):
  4169. bl_space_type = 'VIEW_3D'
  4170. bl_region_type = 'HEADER'
  4171. bl_label = "Proportional Editing"
  4172. bl_ui_units_x = 8
  4173. def draw(self, context):
  4174. layout = self.layout
  4175. tool_settings = context.tool_settings
  4176. col = layout.column()
  4177. if context.mode != 'OBJECT':
  4178. col.prop(tool_settings, "use_proportional_connected")
  4179. sub = col.column()
  4180. sub.active = not tool_settings.use_proportional_connected
  4181. sub.prop(tool_settings, "use_proportional_projected")
  4182. col.separator()
  4183. col.prop(tool_settings, "proportional_edit_falloff", expand=True)
  4184. class VIEW3D_PT_transform_orientations(Panel):
  4185. bl_space_type = 'VIEW_3D'
  4186. bl_region_type = 'HEADER'
  4187. bl_label = "Transform Orientations"
  4188. bl_ui_units_x = 8
  4189. def draw(self, context):
  4190. layout = self.layout
  4191. layout.label(text="Transform Orientations")
  4192. scene = context.scene
  4193. orient_slot = scene.transform_orientation_slots[0]
  4194. orientation = orient_slot.custom_orientation
  4195. row = layout.row()
  4196. col = row.column()
  4197. col.prop(orient_slot, "type", expand=True)
  4198. row.operator("transform.create_orientation", text="", icon='ADD', emboss=False).use = True
  4199. if orientation:
  4200. row = layout.row(align=False)
  4201. row.prop(orientation, "name", text="", icon='OBJECT_ORIGIN')
  4202. row.operator("transform.delete_orientation", text="", icon='X', emboss=False)
  4203. class VIEW3D_PT_gpencil_origin(Panel):
  4204. bl_space_type = 'VIEW_3D'
  4205. bl_region_type = 'HEADER'
  4206. bl_label = "Stroke Placement"
  4207. def draw(self, context):
  4208. layout = self.layout
  4209. tool_settings = context.tool_settings
  4210. gpd = context.gpencil_data
  4211. layout.label(text="Stroke Placement")
  4212. row = layout.row()
  4213. col = row.column()
  4214. col.prop(tool_settings, "gpencil_stroke_placement_view3d", expand=True)
  4215. if tool_settings.gpencil_stroke_placement_view3d == 'SURFACE':
  4216. row = layout.row()
  4217. row.label(text="Offset")
  4218. row = layout.row()
  4219. row.prop(gpd, "zdepth_offset", text="")
  4220. if tool_settings.gpencil_stroke_placement_view3d == 'STROKE':
  4221. row = layout.row()
  4222. row.label(text="Target")
  4223. row = layout.row()
  4224. row.prop(tool_settings, "gpencil_stroke_snap_mode", expand=True)
  4225. class VIEW3D_PT_gpencil_lock(Panel):
  4226. bl_space_type = 'VIEW_3D'
  4227. bl_region_type = 'HEADER'
  4228. bl_label = "Drawing Plane"
  4229. def draw(self, context):
  4230. layout = self.layout
  4231. layout.label(text="Drawing Plane")
  4232. row = layout.row()
  4233. col = row.column()
  4234. col.prop(context.tool_settings.gpencil_sculpt, "lock_axis", expand=True)
  4235. class VIEW3D_PT_gpencil_guide(Panel):
  4236. bl_space_type = 'VIEW_3D'
  4237. bl_region_type = 'HEADER'
  4238. bl_label = "Guides"
  4239. def draw(self, context):
  4240. settings = context.tool_settings.gpencil_sculpt.guide
  4241. layout = self.layout
  4242. layout.label(text="Guides")
  4243. col = layout.column()
  4244. col.active = settings.use_guide
  4245. col.prop(settings, "type", expand=True)
  4246. if settings.type == 'PARALLEL':
  4247. col.prop(settings, "angle")
  4248. row = col.row(align=True)
  4249. col.prop(settings, "use_snapping")
  4250. if settings.use_snapping:
  4251. if settings.type == 'RADIAL':
  4252. col.prop(settings, "angle_snap")
  4253. else:
  4254. col.prop(settings, "spacing")
  4255. if settings.type in {'CIRCULAR', 'RADIAL'}:
  4256. col.label(text="Reference Point")
  4257. row = col.row(align=True)
  4258. row.prop(settings, "reference_point", expand=True)
  4259. if settings.reference_point == 'CUSTOM':
  4260. col.prop(settings, "location", text="Custom Location")
  4261. elif settings.reference_point == 'OBJECT':
  4262. col.prop(settings, "reference_object", text="Object Location")
  4263. if not settings.reference_object:
  4264. col.label(text="No object selected, using cursor")
  4265. class VIEW3D_PT_overlay_gpencil_options(Panel):
  4266. bl_space_type = 'VIEW_3D'
  4267. bl_region_type = 'HEADER'
  4268. bl_parent_id = 'VIEW3D_PT_overlay'
  4269. bl_label = ""
  4270. @classmethod
  4271. def poll(cls, context):
  4272. return context.object and context.object.type == 'GPENCIL'
  4273. def draw_header(self, context):
  4274. layout = self.layout
  4275. layout.label(text={
  4276. 'PAINT_GPENCIL': "Draw Grease Pencil",
  4277. 'EDIT_GPENCIL': "Edit Grease Pencil",
  4278. 'SCULPT_GPENCIL': "Sculpt Grease Pencil",
  4279. 'WEIGHT_GPENCIL': "Weight Grease Pencil",
  4280. 'OBJECT': "Grease Pencil",
  4281. }[context.mode])
  4282. def draw(self, context):
  4283. layout = self.layout
  4284. view = context.space_data
  4285. overlay = view.overlay
  4286. layout.prop(overlay, "use_gpencil_onion_skin", text="Onion Skin")
  4287. col = layout.column()
  4288. row = col.row()
  4289. row.prop(overlay, "use_gpencil_grid", text="")
  4290. sub = row.row()
  4291. sub.active = overlay.use_gpencil_grid
  4292. sub.prop(overlay, "gpencil_grid_opacity", text="Canvas", slider=True)
  4293. row = col.row()
  4294. row.prop(overlay, "use_gpencil_paper", text="")
  4295. sub = row.row()
  4296. sub.active = overlay.use_gpencil_paper
  4297. sub.prop(overlay, "gpencil_paper_opacity", text="Fade 3D Objects", slider=True)
  4298. if context.object.mode == 'PAINT_GPENCIL':
  4299. row = col.row()
  4300. row.prop(overlay, "use_gpencil_fade_layers", text="")
  4301. sub = row.row()
  4302. sub.active = overlay.use_gpencil_fade_layers
  4303. sub.prop(overlay, "gpencil_fade_layer", text="Fade Layers", slider=True)
  4304. if context.object.mode in {'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}:
  4305. layout.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines")
  4306. layout.prop(overlay, "use_gpencil_multiedit_line_only", text="Show Edit Lines only in multiframe")
  4307. layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True)
  4308. class VIEW3D_PT_quad_view(Panel):
  4309. bl_space_type = 'VIEW_3D'
  4310. bl_region_type = 'UI'
  4311. bl_category = "View"
  4312. bl_label = "Quad View"
  4313. bl_options = {'DEFAULT_CLOSED'}
  4314. @classmethod
  4315. def poll(cls, context):
  4316. view = context.space_data
  4317. return view.region_quadviews
  4318. def draw(self, context):
  4319. layout = self.layout
  4320. view = context.space_data
  4321. region = view.region_quadviews[2]
  4322. col = layout.column()
  4323. col.prop(region, "lock_rotation")
  4324. row = col.row()
  4325. row.enabled = region.lock_rotation
  4326. row.prop(region, "show_sync_view")
  4327. row = col.row()
  4328. row.enabled = region.lock_rotation and region.show_sync_view
  4329. row.prop(region, "use_box_clip")
  4330. # Annotation properties
  4331. class VIEW3D_PT_grease_pencil(AnnotationDataPanel, Panel):
  4332. bl_space_type = 'VIEW_3D'
  4333. bl_region_type = 'UI'
  4334. bl_category = "View"
  4335. # NOTE: this is just a wrapper around the generic GP Panel
  4336. class VIEW3D_PT_annotation_onion(AnnotationOnionSkin, Panel):
  4337. bl_space_type = 'VIEW_3D'
  4338. bl_region_type = 'UI'
  4339. bl_category = "View"
  4340. bl_parent_id = 'VIEW3D_PT_grease_pencil'
  4341. # NOTE: this is just a wrapper around the generic GP Panel
  4342. class TOPBAR_PT_annotation_layers(Panel, AnnotationDataPanel):
  4343. bl_space_type = 'VIEW_3D'
  4344. bl_region_type = 'HEADER'
  4345. bl_label = "Layers"
  4346. bl_ui_units_x = 14
  4347. class VIEW3D_PT_view3d_stereo(Panel):
  4348. bl_space_type = 'VIEW_3D'
  4349. bl_region_type = 'UI'
  4350. bl_category = "View"
  4351. bl_label = "Stereoscopy"
  4352. bl_options = {'DEFAULT_CLOSED'}
  4353. @classmethod
  4354. def poll(cls, context):
  4355. scene = context.scene
  4356. multiview = scene.render.use_multiview
  4357. return multiview
  4358. def draw(self, context):
  4359. layout = self.layout
  4360. view = context.space_data
  4361. basic_stereo = context.scene.render.views_format == 'STEREO_3D'
  4362. col = layout.column()
  4363. col.row().prop(view, "stereo_3d_camera", expand=True)
  4364. col.label(text="Display:")
  4365. row = col.row()
  4366. row.active = basic_stereo
  4367. row.prop(view, "show_stereo_3d_cameras")
  4368. row = col.row()
  4369. row.active = basic_stereo
  4370. split = row.split()
  4371. split.prop(view, "show_stereo_3d_convergence_plane")
  4372. split = row.split()
  4373. split.prop(view, "stereo_3d_convergence_plane_alpha", text="Alpha")
  4374. split.active = view.show_stereo_3d_convergence_plane
  4375. row = col.row()
  4376. split = row.split()
  4377. split.prop(view, "show_stereo_3d_volume")
  4378. split = row.split()
  4379. split.active = view.show_stereo_3d_volume
  4380. split.prop(view, "stereo_3d_volume_alpha", text="Alpha")
  4381. class VIEW3D_PT_context_properties(Panel):
  4382. bl_space_type = 'VIEW_3D'
  4383. bl_region_type = 'UI'
  4384. bl_category = "Item"
  4385. bl_label = "Properties"
  4386. bl_options = {'DEFAULT_CLOSED'}
  4387. @staticmethod
  4388. def _active_context_member(context):
  4389. obj = context.object
  4390. if obj:
  4391. object_mode = obj.mode
  4392. if object_mode == 'POSE':
  4393. return "active_pose_bone"
  4394. elif object_mode == 'EDIT' and obj.type == 'ARMATURE':
  4395. return "active_bone"
  4396. else:
  4397. return "object"
  4398. return ""
  4399. @classmethod
  4400. def poll(cls, context):
  4401. import rna_prop_ui
  4402. member = cls._active_context_member(context)
  4403. if member:
  4404. context_member, member = rna_prop_ui.rna_idprop_context_value(context, member, object)
  4405. return context_member and rna_prop_ui.rna_idprop_has_properties(context_member)
  4406. return False
  4407. def draw(self, context):
  4408. import rna_prop_ui
  4409. member = VIEW3D_PT_context_properties._active_context_member(context)
  4410. if member:
  4411. # Draw with no edit button
  4412. rna_prop_ui.draw(self.layout, context, member, object, False)
  4413. # Grease Pencil Object - Multiframe falloff tools
  4414. class VIEW3D_PT_gpencil_multi_frame(Panel):
  4415. bl_space_type = 'VIEW_3D'
  4416. bl_region_type = 'HEADER'
  4417. bl_label = "Multi Frame"
  4418. def draw(self, context):
  4419. gpd = context.gpencil_data
  4420. settings = context.tool_settings.gpencil_sculpt
  4421. layout = self.layout
  4422. col = layout.column(align=True)
  4423. col.prop(settings, "use_multiframe_falloff")
  4424. # Falloff curve
  4425. if gpd.use_multiedit and settings.use_multiframe_falloff:
  4426. layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True)
  4427. class VIEW3D_MT_gpencil_edit_context_menu(Menu):
  4428. bl_label = "Edit Context Menu"
  4429. def draw(self, context):
  4430. layout = self.layout
  4431. is_3d_view = context.space_data.type == 'VIEW_3D'
  4432. layout.operator_context = 'INVOKE_REGION_WIN'
  4433. # Add
  4434. layout.operator("gpencil.stroke_subdivide", text="Subdivide")
  4435. layout.separator()
  4436. # Transform
  4437. layout.operator("transform.transform", text="Shrink/Fatten").mode = 'GPENCIL_SHRINKFATTEN'
  4438. layout.operator("gpencil.stroke_smooth", text="Smooth")
  4439. layout.operator("gpencil.stroke_trim", text="Trim")
  4440. layout.separator()
  4441. # Modify
  4442. layout.menu("VIEW3D_MT_assign_material")
  4443. layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes")
  4444. layout.operator("gpencil.stroke_flip", text="Flip Direction")
  4445. layout.operator_menu_enum("gpencil.stroke_caps_set", text="Toggle Caps", property="type")
  4446. layout.separator()
  4447. layout.operator("gpencil.duplicate_move", text="Duplicate")
  4448. layout.operator("gpencil.copy", text="Copy", icon='COPYDOWN')
  4449. layout.operator("gpencil.paste", text="Paste", icon='PASTEDOWN').type = 'COPY'
  4450. layout.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE'
  4451. layout.menu("VIEW3D_MT_gpencil_copy_layer")
  4452. layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
  4453. layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
  4454. layout.separator()
  4455. layout.operator("gpencil.stroke_join", text="Join").type = 'JOIN'
  4456. layout.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
  4457. layout.menu("GPENCIL_MT_separate", text="Separate")
  4458. layout.operator("gpencil.stroke_split", text="Split")
  4459. op = layout.operator("gpencil.stroke_cyclical_set", text="Close")
  4460. op.type = 'CLOSE'
  4461. op.geometry = True
  4462. layout.separator()
  4463. layout.menu("VIEW3D_MT_mirror")
  4464. layout.menu("VIEW3D_MT_snap")
  4465. layout.separator()
  4466. # Remove
  4467. if is_3d_view:
  4468. layout.menu("GPENCIL_MT_cleanup")
  4469. layout.operator("gpencil.stroke_simplify_fixed", text="Simplify")
  4470. layout.operator("gpencil.stroke_simplify", text="Simplify Adaptive")
  4471. layout.operator("gpencil.stroke_merge", text="Merge")
  4472. layout.menu("VIEW3D_MT_edit_gpencil_delete")
  4473. class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
  4474. bl_space_type = 'VIEW_3D'
  4475. bl_region_type = 'WINDOW'
  4476. bl_label = "Sculpt Context Menu"
  4477. def draw(self, context):
  4478. brush = context.tool_settings.gpencil_sculpt.brush
  4479. layout = self.layout
  4480. if context.mode == 'WEIGHT_GPENCIL':
  4481. layout.prop(brush, "weight")
  4482. layout.prop(brush, "size", slider=True)
  4483. layout.prop(brush, "strength")
  4484. layout.separator()
  4485. # Frames
  4486. layout.label(text="Frames:")
  4487. layout.operator_context = 'INVOKE_REGION_WIN'
  4488. layout.operator("gpencil.blank_frame_add", text="Insert Blank", icon='ADD')
  4489. layout.operator("gpencil.frame_duplicate", text="Duplicate Active", icon='DUPLICATE')
  4490. layout.operator("gpencil.frame_duplicate", text="Duplicate for All Layers", icon='DUPLICATE').mode = 'ALL'
  4491. layout.separator()
  4492. layout.operator("gpencil.delete", text="Delete Active", icon='REMOVE').type = 'FRAME'
  4493. layout.operator("gpencil.active_frames_delete_all", text="Delete All Active Layers", icon='REMOVE')
  4494. class VIEW3D_PT_gpencil_draw_context_menu(Panel):
  4495. bl_space_type = 'VIEW_3D'
  4496. bl_region_type = 'WINDOW'
  4497. bl_label = "Draw Context Menu"
  4498. def draw(self, context):
  4499. brush = context.tool_settings.gpencil_paint.brush
  4500. gp_settings = brush.gpencil_settings
  4501. layout = self.layout
  4502. if brush.gpencil_tool not in {'FILL', 'CUTTER'}:
  4503. layout.prop(brush, "size", slider=True)
  4504. if brush.gpencil_tool not in {'ERASE', 'FILL', 'CUTTER'}:
  4505. layout.prop(gp_settings, "pen_strength")
  4506. layout.separator()
  4507. # Frames
  4508. layout.label(text="Frames:")
  4509. layout.operator_context = 'INVOKE_REGION_WIN'
  4510. layout.operator("gpencil.blank_frame_add", text="Insert Blank", icon='ADD')
  4511. layout.operator("gpencil.frame_duplicate", text="Duplicate Active", icon='DUPLICATE')
  4512. layout.operator("gpencil.frame_duplicate", text="Duplicate for All Layers", icon='DUPLICATE').mode = 'ALL'
  4513. layout.separator()
  4514. layout.operator("gpencil.delete", text="Delete Active", icon='REMOVE').type = 'FRAME'
  4515. layout.operator("gpencil.active_frames_delete_all", text="Delete All Active Layers", icon='REMOVE')
  4516. class VIEW3D_PT_paint_vertex_context_menu(Panel):
  4517. # Only for popover, these are dummy values.
  4518. bl_space_type = 'VIEW_3D'
  4519. bl_region_type = 'WINDOW'
  4520. bl_label = "Vertex Paint Context Menu"
  4521. def draw(self, context):
  4522. layout = self.layout
  4523. brush = context.tool_settings.vertex_paint.brush
  4524. capabilities = brush.vertex_paint_capabilities
  4525. if capabilities.has_color:
  4526. split = layout.split(factor=0.1)
  4527. UnifiedPaintPanel.prop_unified_color(split, context, brush, "color", text="")
  4528. UnifiedPaintPanel.prop_unified_color_picker(split, context, brush, "color", value_slider=True)
  4529. layout.prop(brush, "blend", text="")
  4530. UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True)
  4531. UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength")
  4532. class VIEW3D_PT_paint_texture_context_menu(Panel):
  4533. # Only for popover, these are dummy values.
  4534. bl_space_type = 'VIEW_3D'
  4535. bl_region_type = 'WINDOW'
  4536. bl_label = "Texture Paint Context Menu"
  4537. def draw(self, context):
  4538. layout = self.layout
  4539. brush = context.tool_settings.image_paint.brush
  4540. capabilities = brush.image_paint_capabilities
  4541. if capabilities.has_color:
  4542. split = layout.split(factor=0.1)
  4543. UnifiedPaintPanel.prop_unified_color(split, context, brush, "color", text="")
  4544. UnifiedPaintPanel.prop_unified_color_picker(split, context, brush, "color", value_slider=True)
  4545. layout.prop(brush, "blend", text="")
  4546. if capabilities.has_radius:
  4547. UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True)
  4548. UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength")
  4549. class VIEW3D_PT_paint_weight_context_menu(Panel):
  4550. # Only for popover, these are dummy values.
  4551. bl_space_type = 'VIEW_3D'
  4552. bl_region_type = 'WINDOW'
  4553. bl_label = "Weights Context Menu"
  4554. def draw(self, context):
  4555. layout = self.layout
  4556. brush = context.tool_settings.weight_paint.brush
  4557. UnifiedPaintPanel.prop_unified_weight(layout, context, brush, "weight", slider=True)
  4558. UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True)
  4559. UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength")
  4560. class VIEW3D_PT_sculpt_context_menu(Panel):
  4561. # Only for popover, these are dummy values.
  4562. bl_space_type = 'VIEW_3D'
  4563. bl_region_type = 'WINDOW'
  4564. bl_label = "Sculpt Context Menu"
  4565. def draw(self, context):
  4566. layout = self.layout
  4567. brush = context.tool_settings.sculpt.brush
  4568. capabilities = brush.sculpt_capabilities
  4569. UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True)
  4570. UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength")
  4571. if capabilities.has_auto_smooth:
  4572. layout.prop(brush, "auto_smooth_factor", slider=True)
  4573. if capabilities.has_normal_weight:
  4574. layout.prop(brush, "normal_weight", slider=True)
  4575. if capabilities.has_pinch_factor:
  4576. layout.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
  4577. if capabilities.has_rake_factor:
  4578. layout.prop(brush, "rake_factor", slider=True)
  4579. if capabilities.has_plane_offset:
  4580. layout.prop(brush, "plane_offset", slider=True)
  4581. layout.prop(brush, "plane_trim", slider=True, text="Distance")
  4582. if capabilities.has_height:
  4583. layout.prop(brush, "height", slider=True, text="Height")
  4584. class TOPBAR_PT_gpencil_materials(GreasePencilMaterialsPanel, Panel):
  4585. bl_space_type = 'VIEW_3D'
  4586. bl_region_type = 'HEADER'
  4587. bl_label = "Materials"
  4588. bl_ui_units_x = 14
  4589. @classmethod
  4590. def poll(cls, context):
  4591. ob = context.object
  4592. return ob and ob.type == 'GPENCIL'
  4593. classes = (
  4594. VIEW3D_HT_header,
  4595. VIEW3D_HT_tool_header,
  4596. VIEW3D_MT_editor_menus,
  4597. VIEW3D_MT_transform,
  4598. VIEW3D_MT_transform_base,
  4599. VIEW3D_MT_transform_object,
  4600. VIEW3D_MT_transform_armature,
  4601. VIEW3D_MT_mirror,
  4602. VIEW3D_MT_snap,
  4603. VIEW3D_MT_uv_map,
  4604. VIEW3D_MT_view,
  4605. VIEW3D_MT_view_local,
  4606. VIEW3D_MT_view_cameras,
  4607. VIEW3D_MT_view_navigation,
  4608. VIEW3D_MT_view_align,
  4609. VIEW3D_MT_view_align_selected,
  4610. VIEW3D_MT_view_viewpoint,
  4611. VIEW3D_MT_view_regions,
  4612. VIEW3D_MT_select_object,
  4613. VIEW3D_MT_select_object_more_less,
  4614. VIEW3D_MT_select_pose,
  4615. VIEW3D_MT_select_pose_more_less,
  4616. VIEW3D_MT_select_particle,
  4617. VIEW3D_MT_edit_mesh,
  4618. VIEW3D_MT_edit_mesh_select_similar,
  4619. VIEW3D_MT_edit_mesh_select_by_trait,
  4620. VIEW3D_MT_edit_mesh_select_more_less,
  4621. VIEW3D_MT_select_edit_mesh,
  4622. VIEW3D_MT_select_edit_curve,
  4623. VIEW3D_MT_select_edit_surface,
  4624. VIEW3D_MT_edit_text_context_menu,
  4625. VIEW3D_MT_select_edit_text,
  4626. VIEW3D_MT_select_edit_metaball,
  4627. VIEW3D_MT_edit_lattice_context_menu,
  4628. VIEW3D_MT_select_edit_lattice,
  4629. VIEW3D_MT_select_edit_armature,
  4630. VIEW3D_MT_select_gpencil,
  4631. VIEW3D_MT_select_paint_mask,
  4632. VIEW3D_MT_select_paint_mask_vertex,
  4633. VIEW3D_MT_angle_control,
  4634. VIEW3D_MT_mesh_add,
  4635. VIEW3D_MT_curve_add,
  4636. VIEW3D_MT_surface_add,
  4637. VIEW3D_MT_edit_metaball_context_menu,
  4638. VIEW3D_MT_metaball_add,
  4639. TOPBAR_MT_edit_curve_add,
  4640. TOPBAR_MT_edit_armature_add,
  4641. VIEW3D_MT_armature_add,
  4642. VIEW3D_MT_light_add,
  4643. VIEW3D_MT_lightprobe_add,
  4644. VIEW3D_MT_camera_add,
  4645. VIEW3D_MT_add,
  4646. VIEW3D_MT_image_add,
  4647. VIEW3D_MT_object,
  4648. VIEW3D_MT_object_animation,
  4649. VIEW3D_MT_object_rigid_body,
  4650. VIEW3D_MT_object_clear,
  4651. VIEW3D_MT_object_context_menu,
  4652. VIEW3D_MT_object_shading,
  4653. VIEW3D_MT_object_apply,
  4654. VIEW3D_MT_object_relations,
  4655. VIEW3D_MT_object_parent,
  4656. VIEW3D_MT_object_track,
  4657. VIEW3D_MT_object_collection,
  4658. VIEW3D_MT_object_constraints,
  4659. VIEW3D_MT_object_quick_effects,
  4660. VIEW3D_MT_object_showhide,
  4661. VIEW3D_MT_make_single_user,
  4662. VIEW3D_MT_make_links,
  4663. VIEW3D_MT_brush,
  4664. VIEW3D_MT_brush_paint_modes,
  4665. VIEW3D_MT_paint_vertex,
  4666. VIEW3D_MT_hook,
  4667. VIEW3D_MT_vertex_group,
  4668. VIEW3D_MT_paint_weight,
  4669. VIEW3D_MT_sculpt,
  4670. VIEW3D_MT_hide_mask,
  4671. VIEW3D_MT_particle,
  4672. VIEW3D_MT_particle_context_menu,
  4673. VIEW3D_MT_particle_showhide,
  4674. VIEW3D_MT_pose,
  4675. VIEW3D_MT_pose_transform,
  4676. VIEW3D_MT_pose_slide,
  4677. VIEW3D_MT_pose_propagate,
  4678. VIEW3D_MT_pose_library,
  4679. VIEW3D_MT_pose_motion,
  4680. VIEW3D_MT_pose_group,
  4681. VIEW3D_MT_pose_ik,
  4682. VIEW3D_MT_pose_constraints,
  4683. VIEW3D_MT_pose_showhide,
  4684. VIEW3D_MT_pose_apply,
  4685. VIEW3D_MT_pose_context_menu,
  4686. VIEW3D_MT_bone_options_toggle,
  4687. VIEW3D_MT_bone_options_enable,
  4688. VIEW3D_MT_bone_options_disable,
  4689. VIEW3D_MT_edit_mesh_context_menu,
  4690. VIEW3D_MT_edit_mesh_select_mode,
  4691. VIEW3D_MT_edit_mesh_select_linked,
  4692. VIEW3D_MT_edit_mesh_select_loops,
  4693. VIEW3D_MT_edit_mesh_extrude,
  4694. VIEW3D_MT_edit_mesh_vertices,
  4695. VIEW3D_MT_edit_mesh_edges,
  4696. VIEW3D_MT_edit_mesh_edges_data,
  4697. VIEW3D_MT_edit_mesh_faces,
  4698. VIEW3D_MT_edit_mesh_faces_data,
  4699. VIEW3D_MT_edit_mesh_normals,
  4700. VIEW3D_MT_edit_mesh_normals_select_strength,
  4701. VIEW3D_MT_edit_mesh_normals_set_strength,
  4702. VIEW3D_MT_edit_mesh_normals_average,
  4703. VIEW3D_MT_edit_mesh_shading,
  4704. VIEW3D_MT_edit_mesh_weights,
  4705. VIEW3D_MT_edit_mesh_clean,
  4706. VIEW3D_MT_edit_mesh_delete,
  4707. VIEW3D_MT_edit_mesh_merge,
  4708. VIEW3D_MT_edit_mesh_showhide,
  4709. VIEW3D_MT_paint_gpencil,
  4710. VIEW3D_MT_assign_material,
  4711. VIEW3D_MT_edit_gpencil,
  4712. VIEW3D_MT_edit_gpencil_delete,
  4713. VIEW3D_MT_weight_gpencil,
  4714. VIEW3D_MT_gpencil_animation,
  4715. VIEW3D_MT_gpencil_simplify,
  4716. VIEW3D_MT_gpencil_copy_layer,
  4717. VIEW3D_MT_gpencil_autoweights,
  4718. VIEW3D_MT_gpencil_edit_context_menu,
  4719. VIEW3D_MT_edit_curve,
  4720. VIEW3D_MT_edit_curve_ctrlpoints,
  4721. VIEW3D_MT_edit_curve_segments,
  4722. VIEW3D_MT_edit_curve_clean,
  4723. VIEW3D_MT_edit_curve_context_menu,
  4724. VIEW3D_MT_edit_curve_delete,
  4725. VIEW3D_MT_edit_curve_showhide,
  4726. VIEW3D_MT_edit_surface,
  4727. VIEW3D_MT_edit_font,
  4728. VIEW3D_MT_edit_text_chars,
  4729. VIEW3D_MT_edit_meta,
  4730. VIEW3D_MT_edit_meta_showhide,
  4731. VIEW3D_MT_edit_lattice,
  4732. VIEW3D_MT_edit_armature,
  4733. VIEW3D_MT_armature_context_menu,
  4734. VIEW3D_MT_edit_armature_parent,
  4735. VIEW3D_MT_edit_armature_roll,
  4736. VIEW3D_MT_edit_armature_names,
  4737. VIEW3D_MT_edit_armature_delete,
  4738. VIEW3D_MT_edit_gpencil_transform,
  4739. VIEW3D_MT_edit_gpencil_interpolate,
  4740. VIEW3D_MT_object_mode_pie,
  4741. VIEW3D_MT_view_pie,
  4742. VIEW3D_MT_transform_gizmo_pie,
  4743. VIEW3D_MT_shading_pie,
  4744. VIEW3D_MT_shading_ex_pie,
  4745. VIEW3D_MT_pivot_pie,
  4746. VIEW3D_MT_snap_pie,
  4747. VIEW3D_MT_orientations_pie,
  4748. VIEW3D_MT_proportional_editing_falloff_pie,
  4749. VIEW3D_PT_active_tool,
  4750. VIEW3D_PT_active_tool_duplicate,
  4751. VIEW3D_PT_view3d_properties,
  4752. VIEW3D_PT_view3d_lock,
  4753. VIEW3D_PT_view3d_cursor,
  4754. VIEW3D_PT_collections,
  4755. VIEW3D_PT_object_type_visibility,
  4756. VIEW3D_PT_grease_pencil,
  4757. VIEW3D_PT_annotation_onion,
  4758. VIEW3D_PT_gpencil_multi_frame,
  4759. VIEW3D_PT_quad_view,
  4760. VIEW3D_PT_view3d_stereo,
  4761. VIEW3D_PT_shading,
  4762. VIEW3D_PT_shading_lighting,
  4763. VIEW3D_PT_shading_color,
  4764. VIEW3D_PT_shading_options,
  4765. VIEW3D_PT_shading_options_shadow,
  4766. VIEW3D_PT_shading_options_ssao,
  4767. VIEW3D_PT_gizmo_display,
  4768. VIEW3D_PT_overlay,
  4769. VIEW3D_PT_overlay_guides,
  4770. VIEW3D_PT_overlay_object,
  4771. VIEW3D_PT_overlay_geometry,
  4772. VIEW3D_PT_overlay_motion_tracking,
  4773. VIEW3D_PT_overlay_edit_mesh,
  4774. VIEW3D_PT_overlay_edit_mesh_shading,
  4775. VIEW3D_PT_overlay_edit_mesh_measurement,
  4776. VIEW3D_PT_overlay_edit_mesh_normals,
  4777. VIEW3D_PT_overlay_edit_mesh_freestyle,
  4778. VIEW3D_PT_overlay_edit_curve,
  4779. VIEW3D_PT_overlay_paint,
  4780. VIEW3D_PT_overlay_pose,
  4781. VIEW3D_PT_overlay_sculpt,
  4782. VIEW3D_PT_pivot_point,
  4783. VIEW3D_PT_snapping,
  4784. VIEW3D_PT_proportional_edit,
  4785. VIEW3D_PT_gpencil_origin,
  4786. VIEW3D_PT_gpencil_lock,
  4787. VIEW3D_PT_gpencil_guide,
  4788. VIEW3D_PT_transform_orientations,
  4789. VIEW3D_PT_overlay_gpencil_options,
  4790. VIEW3D_PT_context_properties,
  4791. VIEW3D_PT_paint_vertex_context_menu,
  4792. VIEW3D_PT_paint_texture_context_menu,
  4793. VIEW3D_PT_paint_weight_context_menu,
  4794. VIEW3D_PT_gpencil_sculpt_context_menu,
  4795. VIEW3D_PT_gpencil_draw_context_menu,
  4796. VIEW3D_PT_sculpt_context_menu,
  4797. TOPBAR_PT_gpencil_materials,
  4798. TOPBAR_PT_annotation_layers,
  4799. )
  4800. if __name__ == "__main__": # only for live edit.
  4801. from bpy.utils import register_class
  4802. for cls in classes:
  4803. register_class(cls)