Ultimately, materialized refreshes are just standard SQL under the covers, and I'm unaware of any inbuilt limitation to prohibit the use of smart scans.
I would activate a sql trace on the refresh - and lets have a look at the SQL's that are generated, and then see what's stopping them from being smart scanned.
I did the following simple example here
create materialized view MV1
refresh complete
on demand
as select owner, count(*), sum(object_id) from t
group by owner;
and the refreshes (atomic=true and false respectively) yielded:
/* MV_REFRESH (INS) */INSERT /*+ BYPASS_RECURSIVE_CHECK */ INTO "MCDONAC"."MV1"("OWNER","COUNT(*)","SUM(OBJECT_ID)") SELECT "T"."OWNER",COUNT(*),SUM("T"."OBJECT_ID") FROM "T" "T" GROUP BY "T"."OWNER"
/* MV_REFRESH (INS) */INSERT /*+ BYPASS_RECURSIVE_CHECK APPEND SKIP_UNQ_UNUSABLE_IDX */ INTO "MCDONAC"."MV1"("OWNER","COUNT(*)","SUM(OBJECT_ID)") SELECT "T"."OWNER",COUNT(*),SUM("T"."OBJECT_ID") FROM "T" "T" GROUP BY "T"."OWNER"
the latter looks like a standard insert-append, but you can take the SQL_ID from the trace file and check v$sql for offloading etc.
Hope this helps.